diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 2018-05-24 16:01:30 +0200 |
---|---|---|
committer | Xavier Leroy <xavierleroy@users.noreply.github.com> | 2018-05-26 11:05:13 +0200 |
commit | 9dc1505c01a5748cdd5cac9d978645e2fbc0773c (patch) | |
tree | 6a75c4cb0b096b5744603e37dc4491ac324da8db /cparser | |
parent | 2b2585f39000f7000f296bc5b35c14e70f0c31fe (diff) | |
download | compcert-9dc1505c01a5748cdd5cac9d978645e2fbc0773c.tar.gz compcert-9dc1505c01a5748cdd5cac9d978645e2fbc0773c.zip |
Preserve storage class for functions declared within a block
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();
}
Diffstat (limited to 'cparser')
-rw-r--r-- | cparser/Elab.ml | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/cparser/Elab.ml b/cparser/Elab.ml index dd404d38..6923491a 100644 --- a/cparser/Elab.ml +++ b/cparser/Elab.ml @@ -211,9 +211,11 @@ let enter_or_refine_ident_base local loc env new_id sto ty = | _ -> () end; - (* For a block-scoped, non-"extern" variable, a new declaration - is entered, and it has no linkage. *) - if local && sto <> Storage_extern then begin + (* For a block-scoped, "static" or "auto" or "register" variable, + a new declaration is entered, and it has no linkage. *) + if local + && (sto = Storage_auto || sto = Storage_register || sto = Storage_static) + then begin (new_id, sto, Env.add_ident env new_id sto ty, ty, false) end else begin (* For a file-scoped or "extern" variable, we need to check against @@ -2293,11 +2295,12 @@ let enter_decdefs local loc env sto dl = (name_of_storage_class sto) | _ -> () end; - (* Local function declarations are always treated as extern *) - (* Local variable declarations with default storage are treated as 'auto' *) + (* Local variable declarations with default storage are treated as 'auto'. + Local function declarations with default storage remain with + default storage. *) let sto1 = - if local && isfun then Storage_extern - else if local && sto = Storage_default then Storage_auto + if local && sto = Storage_default && not isfun + then Storage_auto else sto in (* enter ident in environment with declared type, because initializer can refer to the ident *) |