| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
| |
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
|
|
|
|
|
|
| |
Substraction is only allowed for pointer - pointer,
pointer - arithmetic or arithmetic - arithmetic. This also leads
to a retyping error later.
Bug 23357
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Consider:
struct P { int x, y; }
struct S { struct P p; }
struct P p0 = { 1,2 };
struct S s1 = { .p = p0; .p.x = 3 };
ISO C99 and recent versions of Clang initialize s1.p.y to 2, i.e.
the initialization of s1.p.y to p0.y implied by ".p = p0" is kept,
even though the initialization of s1.p.x to p0.x is overwritten
by ".p.x = 3".
GCC, old versions of Clang, and previous versions of CompCert
initialize s1.p.y to the default value 0. I.e. the initialization
".p = p0" is forgotten, leaving default values for the fields of .p
before ".p.x = 3" takes effect.
Implementing the proper ISO C99 semantics in CompCert is difficult,
owing to a mismatch between the intended semantics and the C.init
representation of initializers.
This commit turns the delicate case of reinitialization above
(re-initializing a member of a composite that has already been
initialized as a whole) into a compile-time error.
We will then see if the delicate case occurs in practice and needs
further attention.
|
|
|
|
|
| |
Instead of overwriting the initializer of the anonymous member we
should just keep it.
Bug 23353
|
|
|
|
|
|
|
| |
Sizeof and _Alignof are not allowed on bit-fields
Sizeof and _Alignof are not allowed to be applied to a expression
that designates a bit-field member.
Bug 23311
|
|
|
|
|
|
|
| |
Arrays should decay to pointers except if they are used as operands of sizeof, _Alignof or as
operand of the unary &. The "comma" sequencing operator was missing a "decay" on the type of its second argument. All other operators "decay" their operands correctly.
Bug 23299
Bug 23311
|
|
|
|
|
|
| |
If an anonymous bit-field member is declared wrong, i.e. a wrong
type is used or a too large size is used the error message now
prints <anonymous> instead of an empty string.
Bug 23292
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Do not allow inline on main().
The C99 standard says that in a hosted environment inline shall
not appear in a declaration of main.
Bug 23274
* Added warning for _Noreturn on main().
The C11 standard does not allow any function specifier on the
main function.
Bug 23274
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Module Cerrors is now called Diagnostic and can be used in parts of CompCert other than cparser/
* Replaced eprintf error. Instead of having eprintf msg; exit 2 use the functions from the
Diagnostics module.
* Raise on error before calling external tools.
* Added diagnostics to clightgen.
* Fix error handling of AsmToJson.
* Cleanup error handling of Elab and C2C.
*The implementation of location printing (file & line) is simplified and correctly prints valid filenames with invalid lines.
|
|
|
|
|
|
| |
* Do not pass the env back from for stmt decls.
This is the source of issue #211, the environment from the elaboration of
the declaration and expressions in the for loop should not be passed back.
|
| |
|
|
|
|
|
|
|
| |
In order to correctly support the noinline attribute we must store
whether the function was specified with an inline specifer, had
a noinline attribute or nothing.
Bug 22642
|
|
|
|
|
|
|
| |
The redefinition of a composite with a different tag type is now
a fatal error. This should avoid problems when the composite is
used.
Bug 21542
|
|
|
|
|
|
|
| |
The check tests whether the size calculation of an array overflows
or the array covers half of the available address space and reports
an error in this case.
Bug 21034
|
|
|
|
| |
The noinline attribute prevents functions from inlining.
|
|
|
|
|
|
|
|
|
| |
The unused variable check now uses two passes. One to collect the
used variables and one to report the unused variables.
Futhermore attribute checks are extended to composite declaration.
Also the check is now performed after elaboration.
Bug 19872
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The check test whether the identifier is used at all in the
function and if not issue a warning. It is not tested whether the
usage is reachable at all, so
int i;
if (0)
i;
would not generate a warning. This is the same as gcc/clang does.
The warning is disabled per default, but is active if -Wall is
given.
Bug 19872
|
|
|
|
|
|
| |
As a cosmetic optimization enabled by the static analysis in Cflow, we used to not insert a 'return 0' at end of 'main' if the body of 'main' cannot fall through.
Since this optimization is cosmetic (the back-end will remove the 'return 0' if unused) and since we don't fully trust this static analysis, revert this optimization and always insert 'return 0'.
|
|\
| |
| |
| | |
Improved warnings related to function returns
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This commit introduces a control-flow static analysis over C abstract syntax (file cparser/Cflow.ml) and uses it to
- warn for non-void functions that can return by falling through the body
- warn more precisely for _Noreturn functions that can return
- introduce the "return 0" in "main" functions less often (cosmetic).
For the control-flow analysis, the following conservative approximations are made:
- any "goto" label is reachable
- all cases of a "switch" statement are reachable as soon as the "switch" is reachable (i.e. the switch expression takes all values needed to reach every case)
- the boolean expressions in "if", "while", "do"-"while" and "for" can take true and false values, unless they are compile-time constants.
|
|/
|
|
| |
Minor performance tweak. Printf is more efficient for plain formats involving no boxes.
|
|\ |
|
| |
| |
| |
| |
| | |
- Mark the "noreturn" attribute as related to function types, so that it is correctly attached to the nearest enclosing function type.
- Add this attribute on functions declared / defined _Noreturn (with the C2011 keyword). The information is not used presently but could be useful later.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Introduce Cutil.class_of_attribute to return the class of the given attribute: one among
Attr_type attribute related to types (e.g. "aligned")
Attr_struct attribute related to struct/union/enum types (e.g. "packed")
Attr_function attribute related to function types (e.g. "noreturn")
Attr_name attribute related to variable and function declarations (e.g. "section")
Attr_unknown attribute was not declared
Cutil.declare_attribute is used to associate a class to a custom attribute.
Standard attributes (const, volatile, _Alignas, etc) are Attr_type.
cfronted/C2C.ml: declare the few attributes that CompCert honors currently.
cparser/GCC.ml: a bigger list of attributes taken from GCC, for reference only.
|