diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 2018-05-06 11:30:10 +0200 |
---|---|---|
committer | Xavier Leroy <xavierleroy@users.noreply.github.com> | 2018-05-07 19:19:10 +0200 |
commit | 3e90863161d9d2fc4909d6b1492f786521b166d3 (patch) | |
tree | 75ed15ede6a97c3263e2c7257c54b558fc6b0803 | |
parent | ea3a41bcf894511695bf6118390577f4fe609742 (diff) | |
download | compcert-3e90863161d9d2fc4909d6b1492f786521b166d3.tar.gz compcert-3e90863161d9d2fc4909d6b1492f786521b166d3.zip |
Harden attributes_of_types against out-of-scope structs/unions/enums
In rare cases we can end up querying the attributes of a struct, union
or enum type that is no longer in scope and therefore not bound
in the current environment.
Instead of raising an Env.Error_ exception in this case,
this commit treats such structs / unions / enums as having no
attributes attached to their definitions: only the attributes
carried by the type expression are returned.
One example where this occurs is the following, made possible by
the previous commit ("Revised elaboration of function definitions"):
int f(struct s { int a; } * p) { return p-> a; }
int g(void) { return f(NULL); }
"struct s" is scoped within the definition of f. When we get to
checking the call to f from g, checking that the NULL argument
is compatible with the "struct s *" parameters, we're outside
the scope of "struct s" and its definition is not found in the
current environment.
-rw-r--r-- | cparser/Cutil.ml | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml index f3cd5d14..99b059c0 100644 --- a/cparser/Cutil.ml +++ b/cparser/Cutil.ml @@ -175,11 +175,20 @@ let rec attributes_of_type env t = | TFun(ty, params, vararg, a) -> a | TNamed(s, a) -> attributes_of_type env (unroll env t) | TStruct(s, a) -> - let ci = Env.find_struct env s in add_attributes ci.ci_attr a + begin match Env.find_struct env s with + | ci -> add_attributes ci.ci_attr a + | exception Env.Error(Env.Unbound_tag _) -> a + end | TUnion(s, a) -> - let ci = Env.find_union env s in add_attributes ci.ci_attr a + begin match Env.find_union env s with + | ci -> add_attributes ci.ci_attr a + | exception Env.Error(Env.Unbound_tag _) -> a + end | TEnum(s, a) -> - let ei = Env.find_enum env s in add_attributes ei.ei_attr a + begin match Env.find_enum env s with + | ei -> add_attributes ei.ei_attr a + | exception Env.Error(Env.Unbound_tag _) -> a + end (* Changing the attributes of a type (at top-level) *) (* Same hack as above for array types. *) |