aboutsummaryrefslogtreecommitdiffstats
path: root/cparser/Elab.ml
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2015-04-28 13:17:30 +0200
committerXavier Leroy <xavier.leroy@inria.fr>2015-04-28 13:17:30 +0200
commit74c3e0e8615c2d943eae813b82b11cbfe74d4a82 (patch)
tree1901feb7ca3bc0e2f293b21c582e52b69a84c61f /cparser/Elab.ml
parent916bfc0c4f2a025e9aa642cf616cd8c6ace4ec70 (diff)
downloadcompcert-74c3e0e8615c2d943eae813b82b11cbfe74d4a82.tar.gz
compcert-74c3e0e8615c2d943eae813b82b11cbfe74d4a82.zip
Detect and reject "&" operator applied to "register" local variable or to a bit field.
Diffstat (limited to 'cparser/Elab.ml')
-rw-r--r--cparser/Elab.ml17
1 files changed, 17 insertions, 0 deletions
diff --git a/cparser/Elab.ml b/cparser/Elab.ml
index a1dd552b..ae0ba17b 100644
--- a/cparser/Elab.ml
+++ b/cparser/Elab.ml
@@ -1406,6 +1406,23 @@ let elab_expr loc env a =
let b1 = elab a1 in
if not (is_lvalue b1 || is_function_type env b1.etyp) then
err "argument of '&' is not an l-value";
+ begin match b1.edesc with
+ | EVar id ->
+ begin match wrap Env.find_ident loc env id with
+ | Env.II_ident(Storage_register, _) ->
+ err "address of register variable '%s' requested" id.name
+ | _ -> ()
+ end
+ | EUnop(Odot f, b2) ->
+ let fld = wrap2 field_of_dot_access loc env b2.etyp f in
+ if fld.fld_bitfield <> None then
+ err "address of bit-field '%s' requested" f
+ | EUnop(Oarrow f, b2) ->
+ let fld = wrap2 field_of_arrow_access loc env b2.etyp f in
+ if fld.fld_bitfield <> None then
+ err "address of bit-field '%s' requested" f
+ | _ -> ()
+ end;
{ edesc = EUnop(Oaddrof, b1); etyp = TPtr(b1.etyp, []) }
| UNARY(MEMOF, a1) ->