Skip to content

Commit

Permalink
Merge branch 'master' into newparser
Browse files Browse the repository at this point in the history
  • Loading branch information
jhjourdan committed Feb 26, 2019
2 parents e54fa3b + 235a41a commit 0d80f98
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 25 deletions.
35 changes: 35 additions & 0 deletions Changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
Release 3.5, 2019-02-27
=======================

Bug fixing:
- Modeling error in PowerPC ISA: how register 0 is interpreted when
used as base register for indexed load/stores. The code generated
by CompCert was correct, but was proved correct against the wrong
specification.
- Modeling error in x86 ISA: how flag ZF is set by floating-point
comparisons. Here as well, the code generated by CompCert was
correct, but was proved correct against the wrong specification.
- Revised handling of attributes so that they behave more like in
GCC and Clang. CompCert now distinguishes between attributes that
attach to names (variables, fields, typedefs, structs and unions)
and attributes that attach to objects (variables). In particular,
the `aligned(N)` attribute now attaches to names, while the `_Alignas(N)`
modifier still attaches to objects. This fixes issue 256.
- Issue with NULL as argument to a variadic function on 64-bit platforms
(issue 265)
- Macro __bool_true_false_are_defined was missing from <stdbool.h> (issue 266)

Coq development:
- Can now be entirely rechecked using coqchk
(contributed by Vincent Laporte)
- Support Coq version 8.9.0
- Avoid using "refine mode" when defining Instance
(contributed by Maxime Dénès)
- Do not support Menhir versions more recent than 20181026, because
they will introduce an incompatibility with this CompCert release.

New feature:
- PowerPC port: add __builtin_isel (conditional move) at types int64, uint64,
and _Bool.


Release 3.4, 2018-09-17
=======================

Expand Down
5 changes: 3 additions & 2 deletions cfrontend/C2C.ml
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,9 @@ let attributes = [
("noinline",Cutil.Attr_function);
(* name-related *)
("aligned", Cutil.Attr_name);
("section", Cutil.Attr_name);
("unused", Cutil.Attr_name)
(* object-related *)
("section", Cutil.Attr_object);
("unused", Cutil.Attr_object)
]


Expand Down
9 changes: 1 addition & 8 deletions cparser/Checks.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,12 @@ open Diagnostics
open Cutil
open Env

let attribute_string = function
| AConst -> "const"
| AVolatile -> "volatile"
| ARestrict -> "restrict"
| AAlignas n -> "_Alignas"
| Attr(name, _) -> name

let unknown_attrs loc attrs =
let unknown attr =
let attr_class = class_of_attribute attr in
if attr_class = Attr_unknown then
warning loc Unknown_attribute
"unknown attribute '%s' ignored" (attribute_string attr) in
"unknown attribute '%s' ignored" (name_of_attribute attr) in
List.iter unknown attrs

let unknown_attrs_typ env loc ty =
Expand Down
38 changes: 35 additions & 3 deletions cparser/Cutil.ml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ let rec remove_custom_attributes (names: string list) (al: attributes) =
(* Classification of attributes *)

type attribute_class =
| Attr_name (* Attribute applies to the names being declared *)
| Attr_object (* Attribute applies to the object being declared
(function, global variable, local variable) *)
| Attr_name (* Attribute applies to the name being declared
(object, struct/union member, struct/union/enum tag *)
| Attr_type (* Attribute applies to types *)
| Attr_struct (* Attribute applies to struct, union and enum *)
| Attr_function (* Attribute applies to function types and decls *)
Expand All @@ -111,11 +114,20 @@ let declare_attributes l =

let class_of_attribute = function
| AConst | AVolatile | ARestrict -> Attr_type
| AAlignas _ -> Attr_name
| AAlignas _ -> Attr_object
| Attr(name, args) ->
try Hashtbl.find attr_class (normalize_attrname name)
with Not_found -> Attr_unknown

(* Name for printing an attribute *)

let name_of_attribute = function
| AConst -> "const"
| AVolatile -> "volatile"
| ARestrict -> "restrict"
| AAlignas n -> "_Alignas"
| Attr(name, _) -> name

(* Is an attribute a ISO C standard attribute? *)

let attr_is_standard = function
Expand Down Expand Up @@ -163,7 +175,10 @@ let rec unroll env t =
unroll env (add_attributes_type attr ty)
| _ -> t

(* Extracting the attributes of a type *)
(* Extracting the attributes of a type, including the attributes
attached to typedefs, structs and unions. In other words,
typedefs are unrolled and composite definitions expanded
before extracting the attributes. *)

let rec attributes_of_type env t =
match t with
Expand All @@ -190,6 +205,23 @@ let rec attributes_of_type env t =
| exception Env.Error(Env.Unbound_tag _) -> a
end

(* Extracting the attributes of a type, excluding the attributes
attached to typedefs, structs and unions. In other words,
typedefs are not unrolled and composite definitions are not expanded. *)

let rec attributes_of_type_no_expand t =
match t with
| TVoid a -> a
| TInt(ik, a) -> a
| TFloat(fk, a) -> a
| TPtr(ty, a) -> a
| TArray(ty, sz, a) -> add_attributes a (attributes_of_type_no_expand ty)
| TFun(ty, params, vararg, a) -> a
| TNamed(s, a) -> a
| TStruct(s, a) -> a
| TUnion(s, a) -> a
| TEnum(s, a) -> a

(* Changing the attributes of a type (at top-level) *)
(* Same hack as above for array types. *)

Expand Down
9 changes: 8 additions & 1 deletion cparser/Cutil.mli
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ val remove_custom_attributes : string list -> attributes -> attributes
in the given list of names. *)
val attributes_of_type : Env.t -> typ -> attributes
(* Return the attributes of the given type, expanding typedefs if needed. *)
val attributes_of_type_no_expand : typ -> attributes
(* Return the attributes of the given type, without expanding typedefs. *)
val add_attributes_type : attributes -> typ -> typ
(* Add the given set of attributes to those of the given type. *)
val remove_attributes_type : Env.t -> attributes -> typ -> typ
Expand All @@ -62,7 +64,10 @@ val has_std_alignas : Env.t -> typ -> bool
(* Do the attributes of the type contain the C11 _Alignas attribute *)

type attribute_class =
| Attr_name (* Attribute applies to the names being declared *)
| Attr_object (* Attribute applies to the object being declared
(function, global variable, local variable) *)
| Attr_name (* Attribute applies to the name being declared
(object, struct/union member, struct/union/enum tag *)
| Attr_type (* Attribute applies to types *)
| Attr_struct (* Attribute applies to struct, union and enum *)
| Attr_function (* Attribute applies to function types and decls *)
Expand All @@ -76,6 +81,8 @@ val class_of_attribute: attribute -> attribute_class
have class [Attr_type]. Custom attributes have the class that
was given to them using [declare_attribute], or [Attr_unknown]
if not declared. *)
val name_of_attribute: attribute -> string
(* Name for printing an attribute *)
val attr_inherited_by_members: attribute -> bool
(* Is an attribute of a composite inherited by members of the composite? *)

Expand Down
46 changes: 36 additions & 10 deletions cparser/Elab.ml
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ let get_nontype_attrs env ty =
| Attr_type -> false
| Attr_function -> not (is_function_type env ty)
| _ -> true in
let nta = List.filter to_be_removed (attributes_of_type env ty) in
let nta = List.filter to_be_removed (attributes_of_type_no_expand ty) in
(remove_attributes_type env nta ty, nta)

(* Elaboration of a type specifier. Returns 6-tuple:
Expand Down Expand Up @@ -656,15 +656,31 @@ let rec elab_specifier ?(only = false) loc env specifier =
restrict_check ty;
(!sto, !inline, !noreturn ,!typedef, add_attributes_type !attr ty, env) in

(* As done in CIL, partition !attr into struct-related attributes,
(* Partition !attr into name- and struct-related attributes,
which are returned, and other attributes, which are left in !attr.
The returned struct-related attributes are applied to the
The returned name-or-struct-related attributes are applied to the
struct/union/enum being defined.
The leftover non-struct-related attributes will be applied
to the variable being defined. *)
let get_struct_attrs () =
The leftover attributes (e.g. object attributes) will be applied
to the variable being defined.
If [optmembers] is [None], name-related attributes are not returned
but left in !attr. This corresponds to two use cases:
- A use of an already-defined struct/union/enum. In this case
the name-related attributes should go to the name being declared.
Sending them to the struct/union/enum would cause them to be ignored,
with a warning. The struct-related attributes go to the
struct/union/enum, are ignored, and cause a warning.
- An incomplete declaration of a struct/union. In this case
the name- and struct-related attributes are just ignored,
like GCC does.
*)
let get_definition_attrs optmembers =
let (ta, nta) =
List.partition (fun a -> class_of_attribute a = Attr_struct) !attr in
List.partition
(fun a -> match class_of_attribute a with
| Attr_struct -> true
| Attr_name -> optmembers <> None
| _ -> false)
!attr in
attr := nta;
ta in

Expand Down Expand Up @@ -723,7 +739,8 @@ let rec elab_specifier ?(only = false) loc env specifier =

| [Cabs.Tstruct_union(STRUCT, id, optmembers, a)] ->
let a' =
add_attributes (get_struct_attrs()) (elab_attributes env a) in
add_attributes (get_definition_attrs optmembers)
(elab_attributes env a) in
let (id', env') =
elab_struct_or_union only Struct loc id optmembers a' env in
let ty = TStruct(id', !attr) in
Expand All @@ -732,7 +749,8 @@ let rec elab_specifier ?(only = false) loc env specifier =

| [Cabs.Tstruct_union(UNION, id, optmembers, a)] ->
let a' =
add_attributes (get_struct_attrs()) (elab_attributes env a) in
add_attributes (get_definition_attrs optmembers)
(elab_attributes env a) in
let (id', env') =
elab_struct_or_union only Union loc id optmembers a' env in
let ty = TUnion(id', !attr) in
Expand All @@ -741,7 +759,8 @@ let rec elab_specifier ?(only = false) loc env specifier =

| [Cabs.Tenum(id, optmembers, a)] ->
let a' =
add_attributes (get_struct_attrs()) (elab_attributes env a) in
add_attributes (get_definition_attrs optmembers)
(elab_attributes env a) in
let (id', env') =
elab_enum only loc id optmembers a' env in
let ty = TEnum (id', !attr) in
Expand Down Expand Up @@ -2362,6 +2381,13 @@ let enter_typedefs loc env sto dl =
error loc "initializer in typedef";
if has_std_alignas env ty then
error loc "alignment specified for typedef '%s'" s;
List.iter
(fun a -> match class_of_attribute a with
| Attr_object | Attr_struct ->
error loc "attribute '%s' not allowed in 'typedef'"
(name_of_attribute a)
| _ -> ())
(attributes_of_type_no_expand ty);
match previous_def Env.lookup_typedef env s with
| Some (s',ty') when Env.in_current_scope env s' ->
if equal_types env ty ty' then begin
Expand Down
2 changes: 1 addition & 1 deletion test/regression/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ TESTS=int32 int64 floats floats-basics \
TESTS_COMP=attribs1 bitfields1 bitfields2 bitfields3 bitfields4 \
bitfields5 bitfields6 bitfields7 bitfields8 \
builtins-$(ARCH) packedstruct1 packedstruct2 alignas \
varargs1 varargs2 varargs3 sections alias
varargs1 varargs2 varargs3 sections alias aligned

# Can run, both in compiled mode and in interpreter mode,
# but produce processor-dependent results, so no reference output in Results
Expand Down
12 changes: 12 additions & 0 deletions test/regression/Results/aligned
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
a: size 1, offset mod 16 = 0
b: size 3, offset mod 16 = 0
c: size is that of a pointer, offset mod 16 is good
d: size 1, offset mod 16 = 0
f: size is that of a pointer, offset mod 16 is good
g: size 32, offset mod 16 = 0
h: size 16, offset mod 16 = 0
i: size 16, offset mod 16 = 0
j: size 16, offset mod 16 = 0
T2: size 112, alignment 16
T4: size is that of a pointer, alignment is that of a pointer
t2: size 9, alignment 1
Loading

0 comments on commit 0d80f98

Please sign in to comment.