aboutsummaryrefslogtreecommitdiffstats
path: root/cparser/Cutil.ml
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2018-05-06 11:30:10 +0200
committerXavier Leroy <xavierleroy@users.noreply.github.com>2018-05-07 19:19:10 +0200
commit3e90863161d9d2fc4909d6b1492f786521b166d3 (patch)
tree75ed15ede6a97c3263e2c7257c54b558fc6b0803 /cparser/Cutil.ml
parentea3a41bcf894511695bf6118390577f4fe609742 (diff)
downloadcompcert-kvx-3e90863161d9d2fc4909d6b1492f786521b166d3.tar.gz
compcert-kvx-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.
Diffstat (limited to 'cparser/Cutil.ml')
-rw-r--r--cparser/Cutil.ml15
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. *)