From 0616171c89d3db651b6842338fdf2da9da885aa1 Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Tue, 12 Feb 2019 11:25:22 +0100 Subject: Do not expand type names when floating attributes "up" a declaration During elaboration of type declarators, non-type-related attributes such as "aligned" or "section" are "floated up" so that they apply to the thing being declared. For example, consider: ``` __attribute((aligned(16))) int * p; ``` The attribute is first attached to type `int`, then floated up to type `int *`, so that it finally applies to `p`, giving a 16-aligned pointer to int, and not a naturally-aligned pointer to 16-aligned int. What happens when the non-type-related attribute comes from a typedef? ``` typedef __attribute((aligned(16))) int i16; i16 * p; ``` CompCert used to expand the typedef then float up the attribute, resulting in `p` being a 16-aligned pointer to int. GCC and Clang produce a naturally-aligned pointer, so they do not expand the typedef before floating. The old CompCert behavior is somewhat surprising, and potentially less useful than the GCC/Clang behavior. This commit changes the floating up of non-type-related attributes so that typedefs and struct/union/enum definitions are not expanded when determining which attributes to float up. This is a first step towards mimicking the GCC/Clang behavior. --- cparser/Cutil.ml | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'cparser/Cutil.ml') diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml index ea9713d5..b926e84a 100644 --- a/cparser/Cutil.ml +++ b/cparser/Cutil.ml @@ -163,7 +163,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 @@ -190,6 +193,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. *) -- cgit