aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cfrontend/C2C.ml2
-rw-r--r--common/Sections.ml3
-rw-r--r--common/Sections.mli2
-rw-r--r--cparser/Cprint.ml6
-rw-r--r--cparser/Cutil.ml6
-rw-r--r--cparser/Cutil.mli2
-rw-r--r--cparser/Elab.ml37
-rw-r--r--test/regression/attribs1.c2
8 files changed, 38 insertions, 22 deletions
diff --git a/cfrontend/C2C.ml b/cfrontend/C2C.ml
index 97bfd6d7..b7fe5fb0 100644
--- a/cfrontend/C2C.ml
+++ b/cfrontend/C2C.ml
@@ -1098,7 +1098,7 @@ let convertFundef loc env fd =
Hashtbl.add decl_atom id'
{ a_storage = fd.fd_storage;
a_alignment = None;
- a_sections = Sections.for_function env id' fd.fd_ret;
+ a_sections = Sections.for_function env id' fd.fd_attrib;
a_access = Sections.Access_default;
a_inline = fd.fd_inline && not fd.fd_vararg; (* PR#15 *)
a_loc = loc };
diff --git a/common/Sections.ml b/common/Sections.ml
index b792581f..1c2e8291 100644
--- a/common/Sections.ml
+++ b/common/Sections.ml
@@ -189,8 +189,7 @@ let for_variable env id ty init =
(* Determine sections for a function definition *)
-let for_function env id ty_res =
- let attr = Cutil.attributes_of_type env ty_res in
+let for_function env id attr =
let si_code =
try
(* 1- Section explicitly associated with #use_section *)
diff --git a/common/Sections.mli b/common/Sections.mli
index 8a13fb8a..b83b0bb4 100644
--- a/common/Sections.mli
+++ b/common/Sections.mli
@@ -47,5 +47,5 @@ val use_section_for: AST.ident -> string -> bool
val for_variable: Env.t -> AST.ident -> C.typ -> bool ->
section_name * access_mode
-val for_function: Env.t -> AST.ident -> C.typ -> section_name list
+val for_function: Env.t -> AST.ident -> C.attributes -> section_name list
val for_stringlit: unit -> section_name
diff --git a/cparser/Cprint.ml b/cparser/Cprint.ml
index 2a110104..470c22e5 100644
--- a/cparser/Cprint.ml
+++ b/cparser/Cprint.ml
@@ -156,10 +156,8 @@ let rec dcl ?(pp_indication=true) pp ty n =
dcl pp ty
(fun pp -> fprintf pp " %a" ident id) in
let n' pp =
- begin match a with
- | [] -> n pp
- | _ -> fprintf pp " (%a%t)" attributes a n
- end;
+ attributes pp a;
+ n pp;
fprintf pp "(";
if pp_indication then fprintf pp "@[<hov 0>";
begin match args with
diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml
index f5d5c425..21e6f71e 100644
--- a/cparser/Cutil.ml
+++ b/cparser/Cutil.ml
@@ -92,6 +92,12 @@ let attr_is_standard = function
(* Is an attribute type-related (true) or variable-related (false)? *)
let attr_is_type_related = function
+ | AConst | AVolatile | ARestrict | AAlignas _ -> true
+ | Attr(_, _) -> false
+
+(* Is an attribute related to structs, unions and enum (true) or not (false)? *)
+
+let attr_is_struct_related = function
| Attr(("packed" | "__packed__"), _) -> true
| _ -> false
diff --git a/cparser/Cutil.mli b/cparser/Cutil.mli
index edff9ee1..4906a8a8 100644
--- a/cparser/Cutil.mli
+++ b/cparser/Cutil.mli
@@ -54,6 +54,8 @@ val change_attributes_type : Env.t -> (attributes -> attributes) -> typ -> typ
(* Apply the given function to the top-level attributes of the given type *)
val attr_is_type_related: attribute -> bool
(* Is an attribute type-related (true) or variable-related (false)? *)
+val attr_is_struct_related: attribute -> bool
+ (* Is an attribute related to structs, unions and enum (true) or not (false)? *)
val attr_inherited_by_members: attribute -> bool
(* Is an attribute of a composite inherited by members of the composite? *)
val strip_attributes_type: typ -> attribute list -> typ
diff --git a/cparser/Elab.ml b/cparser/Elab.ml
index 1bfc2d11..951ae5b3 100644
--- a/cparser/Elab.ml
+++ b/cparser/Elab.ml
@@ -477,6 +477,13 @@ let typespec_rank = function (* Don't change this *)
let typespec_order t1 t2 = compare (typespec_rank t1) (typespec_rank t2)
+(* Auxiliary for type declarator elaboration. Remove the non-type-related
+ attributes from the given type and return those attributes separately. *)
+
+let get_nontype_attrs env ty =
+ let (ta, nta) = List.partition attr_is_type_related (attributes_of_type env ty) in
+ (change_attributes_type env (fun _ -> ta) ty, nta)
+
(* Is a specifier an anonymous struct/union in the sense of ISO C2011? *)
let is_anonymous_composite spec =
@@ -528,14 +535,14 @@ let rec elab_specifier keep_ty ?(only = false) loc env specifier =
let simple ty = (!sto, !inline, !noreturn ,!typedef, add_attributes_type !attr ty, env) in
- (* As done in CIL, partition !attr into type-related attributes,
+ (* As done in CIL, partition !attr into struct-related attributes,
which are returned, and other attributes, which are left in !attr.
- The returned type-related attributes are applied to the
+ The returned struct-related attributes are applied to the
struct/union/enum being defined.
- The leftover non-type-related attributes will be applied
+ The leftover non-struct-related attributes will be applied
to the variable being defined. *)
- let get_type_attrs () =
- let (ta, nta) = List.partition attr_is_type_related !attr in
+ let get_struct_attrs () =
+ let (ta, nta) = List.partition attr_is_struct_related !attr in
attr := nta;
ta in
@@ -594,21 +601,21 @@ let rec elab_specifier keep_ty ?(only = false) loc env specifier =
| [Cabs.Tstruct_union(STRUCT, id, optmembers, a)] ->
let a' =
- add_attributes (get_type_attrs()) (elab_attributes env a) in
+ add_attributes (get_struct_attrs()) (elab_attributes env a) in
let (id', env') =
elab_struct_or_union keep_ty only Struct loc id optmembers a' env in
(!sto, !inline, !noreturn, !typedef, TStruct(id', !attr), env')
| [Cabs.Tstruct_union(UNION, id, optmembers, a)] ->
let a' =
- add_attributes (get_type_attrs()) (elab_attributes env a) in
+ add_attributes (get_struct_attrs()) (elab_attributes env a) in
let (id', env') =
elab_struct_or_union keep_ty only Union loc id optmembers a' env in
(!sto, !inline, !noreturn, !typedef, TUnion(id', !attr), env')
| [Cabs.Tenum(id, optmembers, a)] ->
let a' =
- add_attributes (get_type_attrs()) (elab_attributes env a) in
+ add_attributes (get_struct_attrs()) (elab_attributes env a) in
let (id', env') =
elab_enum only loc id optmembers a' env in
(!sto, !inline, !noreturn, !typedef, TEnum(id', !attr), env')
@@ -641,7 +648,8 @@ and elab_type_declarator keep_ty loc env ty kr_ok = function
| Cabs.JUSTBASE ->
((ty, None), env)
| Cabs.ARRAY(d, cv_specs, sz) ->
- let a = elab_cvspecs env cv_specs in
+ let (ty, a) = get_nontype_attrs env ty in
+ let a = add_attributes a (elab_cvspecs env cv_specs) in
let sz' =
match sz with
| None ->
@@ -659,22 +667,25 @@ and elab_type_declarator keep_ty loc env ty kr_ok = function
Some 1L in (* produces better error messages later *)
elab_type_declarator keep_ty loc env (TArray(ty, sz', a)) kr_ok d
| Cabs.PTR(cv_specs, d) ->
- let a = elab_cvspecs env cv_specs in
+ let (ty, a) = get_nontype_attrs env ty in
+ let a = add_attributes a (elab_cvspecs env cv_specs) in
elab_type_declarator keep_ty loc env (TPtr(ty, a)) kr_ok d
| Cabs.PROTO(d, (params, vararg)) ->
elab_return_type loc env ty;
+ let (ty, a) = get_nontype_attrs env ty in
let params',env' = elab_parameters keep_ty env params in
let env = if keep_ty then Env.add_types env env' else env in
- elab_type_declarator keep_ty loc env (TFun(ty, Some params', vararg, [])) kr_ok d
+ elab_type_declarator keep_ty loc env (TFun(ty, Some params', vararg, a)) kr_ok d
| Cabs.PROTO_OLD(d, params) ->
elab_return_type loc env ty;
+ let (ty, a) = get_nontype_attrs env ty in
match params with
| [] ->
- elab_type_declarator keep_ty loc env (TFun(ty, None, false, [])) kr_ok d
+ elab_type_declarator keep_ty loc env (TFun(ty, None, false, a)) kr_ok d
| _ ->
if not kr_ok || d <> Cabs.JUSTBASE then
fatal_error loc "illegal old-style K&R function definition";
- ((TFun(ty, None, false, []), Some params), env)
+ ((TFun(ty, None, false, a), Some params), env)
(* Elaboration of parameters in a prototype *)
diff --git a/test/regression/attribs1.c b/test/regression/attribs1.c
index 808610b7..0650b189 100644
--- a/test/regression/attribs1.c
+++ b/test/regression/attribs1.c
@@ -24,7 +24,7 @@ __attribute((__section__("myconst"))) const int e = 12;
const char filler4 = 1;
__attribute((__section__("myconst"))) const int f = 34;
-__attribute((__section__("mycode"))) int myfunc(int x) { return x + 1; }
+__attribute((__section__("mycode"))) int * myfunc(int * x) { return x + 1; }
/* Alignment with typedefs and structs */