| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* bug 24268: avoid assertion after reporting error for invalid call to builtin_debug
* bug 24268, remove duplicated warning tag in lexer messages
* bug 24268, fix spelling in array element designator message
* bug 24268, unify 'consider adding option ...' messages
* bug 24268, add spacing for icbi operands
* bug 24268, uniform use of Ignored_attributes class for identical warnings
* bug 24268, unify message for 'assignment to const type' to error from error/fatal error
* bug 24268, in handcrafted.messages, "a xxx have been recognized" -> "a xxx has been recognized"
|
|
|
|
|
|
| |
Since the following offsetof cannot handle bit-fields we should
stop earlier.
Bug 24480
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Refactor common code of alignas.
Instead of working on attributes the function now works directly
on the type since the check always performed an extraction of
attributes from a type.
Bug 23393
* Attach _Alignas to the name.
Bug 23393
* Attach "aligned" attributes to names
So that __attribute((aligned(N))) remains consistent with _Alignas(N).
gcc and clang apply "aligned" attributes to names, with a special case
for typedefs:
typedef __attribute((aligned(16))) int int_al_16;
int_al_16 * p;
__attribute((aligned(16))) int * q;
For gcc, p is naturally-aligned pointer to 16-aligned int and
q is 16-aligned pointer to naturally-aligned int.
For CompCert with this commit, both p and q are 16-aligned pointers
to naturally-aligned int.
* Resurrect the alignment test involving typedef
The test was removed because it involved an _Alignas in a typedef,
which is no longer supported. However the same effect can be achieved
with an "aligned" attribute, which is still supported in typedef.
|
|
|
|
|
|
| |
Instead of performing the check only for parameters of function
definitions also perform it for function declarations.
Bug 23393
|
|
|
|
|
|
|
| |
The new diagnostic triggers if an `_Alignas` or an `aligned` attribute
or a `packed` attribute requests an alignment smaller than the natural alignment.
Bug 23389
|
|
|
|
|
|
|
|
|
|
|
| |
The C11 standard disallows the usage of _Alignas for:
- Bit-field members of struct or union types
- Typedefs
- Function Defintions
- Parameters of functions
It is still allowed to use the gcc attribute for these constructs.
Bug 23391
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We used to recognize attribute(("aligned"(N))) and map it to _Alignas(N)
during elaboration.
However, we want to restrict the places where _Alignas can occur, as
standardized in ISO C11, while leaving more freedom for the placement
of the "aligned" attribute.
As a first step in this direction, this commit keeps the "aligned"
attribute unchanged in the AST, and distinct from _Alignas attributes.
Both attributes are honored when it comes to determining the actual
alignment of a type.
|
|
|
|
|
|
| |
Restrict is only allowed for pointers whose referenced type is an
object type or incomplete type, but not a function type.
Bug 23397
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Add diagnostic for type qualified arrays that occur in the wrong place
Arrays with type qualifiers (e.g. int t[const 5]) are only allowed as
function parameters and for them
only the outermost array type derivation.
Bug 23400
* Keep attributes from array for argument conversion
Type qualifiers of arrays in function parameters are just syntactic sugar
to allow adding them to the resulting pointer type. Hence, when a
qualified array type such as `int t[const 5]` decays into a pointer type
during argument conversion, the pointer type should be qualified, e.g. `int * const t`.
|
|
|
|
|
|
| |
Tentative static definitions with incomplete type are not allowed
in C99. However most popular compilers support them and warn
about them.
Bug 23377
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Error for structs with only flex array member
Flexible array members are only allowed if another member exists.
Bug 23324
* Added checks for nesting of structs with flex array members
Warn if a struct with a flex array member is used as array element
or member of another struct. Such usage is dubious.
Bug 23324
Don't warn if the struct-with-flex-array is a member of an union.
|
|
|
|
|
|
| |
Since the parameter name gets used in other error messages it
results in messages without names.
Bug 24283
|
|
|
|
|
|
|
| |
It's meant as a Boolean (byte-swap or not), so any other value is dangerous.
The error message is the generic "ill-formed 'packed' attribute".
Maybe we don't need a custom error message.
|
|
|
|
| |
__builtin_offsetof(struct s, f) is an error if f is a bit-field.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
CompCert has two implementations of sizeof, alignof and offsetof (byte offset of a struct field):
- the reference implementation, in Coq, from cfrontend/Ctypes.v
- the implementation used during elaboration, in OCaml, from cparser/Cutil.ml
The reference Coq implementation is used as much as possible, but sometimes during elaboration the size of a type must be computed (e.g. to compute array sizes), or the offset of a field (e.g. to evaluate __builtin_offsetof), in which case the OCaml implementation is used.
This causes issues with packed structs. Currently, the cparser/Cutil.ml functions ignore the "packed" attribute on structs. Their results disagree with the "true" sizes, alignments and offsets computed by the cfrontend/Ctypes.v functions after source-to-source transformation of packed structs as done in cparser/PackedStruct.ml. For example:
```
struct __packed__(1) s { char c; short s; int i; };
assert (__builtin_offsetof(struct s, i) == 3);
assert (sizeof(struct s) = sizeof(char[sizeof(struct s)]));
```
The two assertions fail. In the first assertion, __builtin_offsetof is elaborated to 4, because the packed attribute is ignored during elaboration. In the second assertion, the type `char[sizeof(struct s)]` is elaborated to `char[8]`, again because the packed attribute is ignored during elaboration, while the other `sizeof(struct s)` is computed as 7 after the source-to-source transformation of packed structs.
This commit changes the cparser/Cutil.ml functions so that they take the packed attribute into account when computing sizeof, alignof, offsetof, and struct_layout.
Related changes:
* cparser/Cutil: add `packing_parameters` function to extract packing info from attributes
* cparser/Cutil: refactor and share more code between sizeof_struct, offsetof, and struct_layout
* cparser/Elab: check the alignment parameters given in packed attributes. (The check was previously done in cparser/PackedStruct.ml but now it would come too late.)
* cparser/Elab: refactor the checking of alignment parameters between _Alignas, attribute((aligned)), __packed__, and attribute((packed)).
* cparser/PackedStructs: simplify the code, some functionality was moved to cparser/Cutil, other to cparser/Elab
* cfrontend/C2C: raise an "unsupported" error if a packed struct is defined and -fpacked-structs is not given. Before, the packed attribute would be silently ignored, but now doing so would cause inconsistencies between cfrontend/ and cparser/.
* test/regression/packedstruct1.c: add tests to compare the sizes and the offsets produced by the elaborator with those obtained after elaboration.
|
|
|
|
|
| |
It is not allowed in C to have a parameter in a parameter list
without an identifier.
Bug 24283
|
|
|
|
|
|
| |
Since a non modifiable lvalue is an invalid asm output it should
be checked earlier, otherwise this leads to a retyping error
later.
Bug 24285
|
|
|
|
|
|
| |
Fix various typos in diagnostic messages and unified wording and
capitalization.
Bug 23850
|
|
|
|
| |
The `_Alignas(expr)` construct is not C11, only `_Alignas(type)` is.
|
|
|
|
|
|
|
| |
Nonstatic inline functions can be expanded in several compilation units.
The static variables in question may differ between different expansions.
This is a manual merge and adaptation of pull request #P95 by @bschommer.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Before, we would pass just the `ctx_vararg` component of the context
to `elab_expr` as a Boolean argument.
For future extensions, we will need to pass more of the context to
`elab_expr`, so why not pass the whole context?
This is what this commit does. The `stmt_context` type is renamed
`elab_context` and its definition is moved earlier. The `ctx`
argument is passed as is from `elab_stmt` to `elab_expr`.
|
|
|
|
|
|
|
| |
The current check for redefinition is too strict, ruling out e.g.
```
typedef int t;
void f(void) { typedef char t; }
```
|
|
|
|
| |
Consistently with _Noreturn, anonymous structs, etc.
|
|
|
|
|
|
| |
As the standard says (and is already implemented) an _Alignas(0)
does not change the alignment at all. The same holds for the gcc
attribute.
Bug 23387
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Allow strings literals as lvalues.
Strings and WStrings literals are lvalues, thus it is allowed to take their
addresses.
Bug 23356.
* String literals have types "array of (wide) char", not "pointer to (wide) char"
The pointer types were a leftover from the early, CIL-based C frontend.
* Remove special case for sizeof("string literal") during elaboration
No longer needed now that literals have array types.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a follow-up to the introduction of the Storage_auto storage class
in commit 760e422.
For functions declared within a block, we used to set their storage class
to "extern":
{ {
int f(void); ---> extern int f(void);
} }
This helped enter_or_refine_ident understand that those declarations
have linkage.
Now that we have Storage_auto, this commit teaches enter_or_refine_ident
that local declarations have no linkage if auto or static, and have
linkage if extern or default.
Then, there is no need to change storage class to extern for
locally-declared functions.
In turn, this improves the "extern-after-definition" warning recently
introduced, avoiding a bizarre warning in the following case:
int foo(void){return 0;}
int main(void){
int foo(void);
return foo();
}
|
|
|
|
|
|
|
|
|
| |
Warning for change of storage class after the definition of a function
from default storage class to extern storage class. This only plays a
role if the function is also declared inline, since for inline functions
with default storage class no code is generated, but for inline functions
with extern storage class code should be generated.
Bug 23512
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Change elab_type_declarator and elab_fundef_name so that the latter
returns two environments: the first one takes into account
struct/union definitions from the function return type,
while the second one also contains bindings for function
parameters and struct/union definitions from the function parameter list.
To this end the "kr_ok" bool argument of elab_type_declarator is
repurposed and renamed "fundef". It controls not just whether
K&R function declarators are supported, but also which bindings
the returned environment contains.
Change elab_fundef to adapt to the changes in elab_fundef_name
and to maintain two environments:
- the global environment, enriched with struct/union definitions from
the function return type, and with the function binding itself;
- the local environment, used for elaborating the body of the
function, which also contains bindings for function parameters
and struct/union definitions from the function parameter list.
Change elab_funbody so that it does not open a new scope for elaborating
the body, even though the body is represented as a block in the AST.
The standard says that the function body is processed in the same
scope where function parameters are declared, so that the following
is illegal:
int f(int x) { double x; ... }
Introduce a variant enter_or_refine_function of enter_or_refine_ident
where the fresh identifier to use (if no earlier declaration is found)
is created in advance in an earlier scope. This helps implement the
proper scoping of function names.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Partial revert of commit ec95665e087d39e29ece455b90e7d5918dc88cee.
That commit introduced a "keep_ty" parameter to type elaboration
functions telling them to keep struct/union definitions occurring
in function parameter lists and lift them to the outer environment.
By setting keep_ty to true, the following could typecheck:
int f(struct s { int a; } x) { return x.a; }
However, "struct s" would escape the scope of the function definition
and leak to the top-level environment, which is not correct.
In subsequent commits we'll address the issues above differently,
in a way that does not need the "keep_ty = true" behavior.
|
|
|
|
|
|
| |
The new warning is raise for function declaration after a function
definition that introduce new attributes, which are ignored.
Bug 23385
|
|
|
|
|
|
| |
The C standards says that either both types must be pointer to
complete compatible or incomplete compatible types.
Bug 23631
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Check for static and extern variables in for
The declaration inside of a for statement is not allowed to have
static or extern storage duration.
Bug 23330
* Also check that the declared variables don't have function types.
* Also checks that no typedefs occur in 'for' declarations.
* Simplify the `elab_declarations` function. It's used only to elaborate the whole program, and the resulting declarations and environment are ignored. So, replace `elab_declarations` by a simpler iteration over the program in `elab_program`.
|
|
|
|
|
| |
Empty declarations in K&R function parameters are not allowed
by the C standard.
Bug 23375
|
|
|
|
| |
The type of array elements must be complete.
Bug 23341
|
| |
|
|
|
|
| |
Report an error in this case.
|
|
|
|
|
|
|
|
|
|
|
|
| |
The Elab pass checks that the argument of 'case' is a compile-time constant
expression. This commit records the value of this expression in the
C.Scase AST generated by Elab, so that it can be used for further
diagnostics, i.e. checking (in Elab) for duplicate cases.
Note that C2C ignores the recorded value and recomputes the value of
the expression using Ceval.integer_expr. This is intentional:
Ceval.integer_expr is more trustworthy, as it is formally verified
against the CompCert C semantics.
|
|
|
|
| |
Report an error in this case.
|
|
|
|
| |
Typedefs should have a name and also should not contain _Noreturn.
Bug 23381
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit checks *during elaboration* that initializers for global
variables or local static variables are compile-time constants.
Before this commit, some non-constant initializers were detected
later in the C2C pass, but others were eliminated by the Cleanup
pass before being checked, and yet others could cause the Rename pass
to abort.
To determine which variables are constant l-values, we leverage
the recent addition of the Storage_auto storage class and base
the determination on the storage class of the identifier:
'auto' or 'register' is not constant, the others are constant.
|
|
|
|
|
| |
Enum tags, struct tags and union tags share a common namespace, thus having
an enum with the same tag as a struct or union is not allowed.
Bug 23548
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously, CompCert would just ignore the `auto` keyword, thus accepting
incorrect top-level definitions such as
```
auto int x;
auto void f(auto int x) { }
```
This commit introduces `auto` as a proper storage class
(Storage_auto constructor in the C AST).
It adds diagnostics for misuses of `auto`, often patterned after the
existing diagnostics for misuses of `register`.
Some error messages were corrected ("storage-class" -> "storage class")
or made closer to those of clang.
Finally, in the generated C AST and in C typing environments,
block-scoped variables without an explicit storage class are recorded
as Storage_auto instead of Storage_default. This is semantically correct
(block-scoped variables default to `auto` behavior) and will help us
distinguishing block-scoped variables from file-scoped variables
in later developments.
|
|
|
|
| |
Forward declarations of enums are not allowed in C99, however it is possible to
have an empty enum declaration after the enum was defined.
|
|
|
|
|
|
| |
In the case of pointer subtraction both side can be pointers, for
example if the difference between two array cells is calculated,
so we need to check that both sides have complete types.
Bug 23312
|
|
|
|
|
|
|
|
|
|
|
|
| |
After calling enter_or_refine for a function identifier we need to keep
the combined attributes. Here is an example where it makes a difference:
```
_Noreturn void f(int x);
void f(int x) { }
```
Before this commit, the `_Noreturn` on the declaration is ignored when checking the definition.
Bug 23385
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#81)
* Added check for redefinition of globals.
Since Cleanup may remove duplicated static functions or global
definitions we need to check for duplication during elaboration,
not just in C2C.
Bug 23410
* Do not eliminate unreferenced static variables with initializers
This way all initialized variables make it to the C2C pass,
where the initializers are checked for constant-ness.
Bug 23410
|
|
|
|
|
|
|
| |
Examples such as the following were accepted but are invalid ISO C:
char c[4] = 42;
struct S { int x, y; } = 42;
This commit rejects such initializations at top-level.
Bug 23372
|
|
|
|
|
|
| |
It is allowed to define a composite within a bitfield size
expression using for example sizeof.
Bug 23360
|