summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cparser/StructAssign.ml18
-rw-r--r--test/regression/Makefile2
-rw-r--r--test/regression/struct9.c13
3 files changed, 24 insertions, 9 deletions
diff --git a/cparser/StructAssign.ml b/cparser/StructAssign.ml
index 51cb489..925170b 100644
--- a/cparser/StructAssign.ml
+++ b/cparser/StructAssign.ml
@@ -133,21 +133,23 @@ let transf_assign env lhs rhs =
(* Detect invariant l-values *)
-let rec invariant_lvalue e =
+let not_volatile env ty = not (List.mem AVolatile (attributes_of_type env ty))
+
+let rec invariant_lvalue env e =
match e.edesc with
| EVar _ -> true
- | EUnop(Oderef, {edesc = EVar _}) -> true (* to check *)
- | EUnop(Odot _, e1) -> invariant_lvalue e1
+ | EUnop(Oderef, {edesc = EVar _; etyp = ty}) -> not_volatile env ty
+ | EUnop(Odot _, e1) -> invariant_lvalue env e1
| _ -> false
(* Bind a l-value to a temporary variable if it is not invariant. *)
-let rec bind_lvalue e fn =
+let rec bind_lvalue env e fn =
match e.edesc with
| EBinop(Ocomma, e1, e2, _) ->
- ecomma e1 (bind_lvalue e2 fn)
+ ecomma e1 (bind_lvalue env e2 fn)
| _ ->
- if invariant_lvalue e then
+ if invariant_lvalue env e then
fn e
else begin
let tmp = new_temp (TPtr(e.etyp, [])) in
@@ -162,8 +164,8 @@ type context = Val | Effects
let rec transf_expr env ctx e =
match e.edesc with
| EBinop(Oassign, lhs, rhs, _) when is_composite_type env lhs.etyp ->
- bind_lvalue (transf_expr env Val lhs) (fun l ->
- bind_lvalue (transf_expr env Val rhs) (fun r ->
+ bind_lvalue env (transf_expr env Val lhs) (fun l ->
+ bind_lvalue env (transf_expr env Val rhs) (fun r ->
let e' = transf_assign env l r in
if ctx = Val then ecomma e' l else e'))
| EConst c -> e
diff --git a/test/regression/Makefile b/test/regression/Makefile
index c1925c7..a385cc4 100644
--- a/test/regression/Makefile
+++ b/test/regression/Makefile
@@ -16,7 +16,7 @@ TESTS=bitfields1 bitfields2 bitfields3 bitfields4 \
# Other tests: should compile to .s without errors (but expect warnings)
EXTRAS=annot1 commaprec expr2 expr3 expr4 extern1 funct2 funptr1 init1 \
init2 init3 init4 pragmas ptrs1 ptrs2 sizeof1 struct1 struct2 struct3 \
- struct4 struct5 struct6 types1 volatile1
+ struct4 struct5 struct6 struct9 types1 volatile1
# Test known to fail
FAILURES=funct1 varargs1
diff --git a/test/regression/struct9.c b/test/regression/struct9.c
new file mode 100644
index 0000000..fae137c
--- /dev/null
+++ b/test/regression/struct9.c
@@ -0,0 +1,13 @@
+struct S1 {
+ unsigned char f0;
+ short f1;
+};
+
+struct S1 g_77 = {0x73,9};
+struct S1 * volatile g_85 = &g_77;
+struct S1 g_204 = {0xAD,0x9086};
+
+void func_1(void)
+{
+ *g_85 = g_204;
+}