diff options
author | Xavier Leroy <xavierleroy@users.noreply.github.com> | 2018-04-26 18:00:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-26 18:00:36 +0200 |
commit | f1d9a90486ac2744e0f2096eeaeedac117af5b9a (patch) | |
tree | 17da3fcddc04d9710f245a64e6124d7d13807c6a /cparser/Elab.ml | |
parent | 7d91167706b72103ddf9f4088cf02dd9761fdf47 (diff) | |
download | compcert-kvx-f1d9a90486ac2744e0f2096eeaeedac117af5b9a.tar.gz compcert-kvx-f1d9a90486ac2744e0f2096eeaeedac117af5b9a.zip |
Earlier, more comprehensive check for constant initializers (#88)
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.
Diffstat (limited to 'cparser/Elab.ml')
-rw-r--r-- | cparser/Elab.ml | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/cparser/Elab.ml b/cparser/Elab.ml index 55764c3c..dddbd03b 100644 --- a/cparser/Elab.ml +++ b/cparser/Elab.ml @@ -2236,9 +2236,6 @@ let enter_decdefs local loc env sto dl = fatal_error loc "'%s' has incomplete type" s; (* process the initializer *) let (ty', init') = elab_initializer loc env1 s ty init in - (* if (sto = Storage_static || not local) then - * (\* Check for constant initializer for static and global variables *\) - * is_constant_init env loc init'; *) (* update environment with refined type *) let env2 = Env.add_ident env1 id sto' ty' in (* check for incomplete type *) @@ -2252,6 +2249,12 @@ let enter_decdefs local loc env sto dl = else begin (* Global definition *) emit_elab ~linkage env2 loc (Gdecl(sto', id, ty', init')); + (* Make sure the initializer is constant. *) + begin match init' with + | Some i when not (Ceval.is_constant_init env2 i) -> + error loc "initializer is not a compile-time constant" + | _ -> () + end; (decls, env2) end in let (decls, env') = List.fold_left enter_decdef ([], env) dl in |