diff options
-rw-r--r-- | cparser/StructAssign.ml | 18 | ||||
-rw-r--r-- | test/regression/Makefile | 2 | ||||
-rw-r--r-- | test/regression/struct9.c | 13 |
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; +} |