diff options
author | Eric Botcazou <ebotcazou@multimania.com> | 2002-03-21 09:39:18 +0000 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2002-03-21 01:39:18 -0800 |
commit | 312687cfa88b0e5ee2600e0349bf285b826521b9 (patch) | |
tree | db9e6c3c3b0671407dbf927358b92c97787e9d8d /gcc | |
parent | 48f90839b0860bf9f286f0f13972c4401caf9395 (diff) | |
download | gcc-312687cfa88b0e5ee2600e0349bf285b826521b9.zip gcc-312687cfa88b0e5ee2600e0349bf285b826521b9.tar.gz gcc-312687cfa88b0e5ee2600e0349bf285b826521b9.tar.bz2 |
re PR c/5354 (function call with two statement expressions yields incorrect result)
PR c/5354
* c-common.c (c_expand_expr): Preserve result of a statement
expression if needed.
Co-Authored-By: Richard Henderson <rth@redhat.com>
From-SVN: r51121
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/c-common.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20020320-1.c | 23 |
3 files changed, 44 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0a06dbd..56349e5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2002-03-21 Eric Botcazou <ebotcazou@multimania.com> + Richard Henderson <rth@redhat.com> + + PR c/5354 + * c-common.c (c_expand_expr): Preserve result of a statement + expression if needed. + 2002-03-21 Jakub Jelinek <jakub@redhat.com> PR bootstrap/4195 diff --git a/gcc/c-common.c b/gcc/c-common.c index 91f2a20..2892059 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -3574,6 +3574,7 @@ c_expand_expr (exp, target, tmode, modifier) { tree rtl_expr; rtx result; + bool preserve_result = false; /* Since expand_expr_stmt calls free_temp_slots after every expression statement, we must call push_temp_slots here. @@ -3600,12 +3601,24 @@ c_expand_expr (exp, target, tmode, modifier) if (TREE_CODE (last) == SCOPE_STMT && TREE_CODE (expr) == EXPR_STMT) - TREE_ADDRESSABLE (expr) = 1; + { + TREE_ADDRESSABLE (expr) = 1; + preserve_result = true; + } } expand_stmt (STMT_EXPR_STMT (exp)); expand_end_stmt_expr (rtl_expr); + result = expand_expr (rtl_expr, target, tmode, modifier); + if (preserve_result && GET_CODE (result) == MEM) + { + if (GET_MODE (result) != BLKmode) + result = copy_to_reg (result); + else + preserve_temp_slots (result); + } + pop_temp_slots (); return result; } diff --git a/gcc/testsuite/gcc.c-torture/execute/20020320-1.c b/gcc/testsuite/gcc.c-torture/execute/20020320-1.c new file mode 100644 index 0000000..05f72c6 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20020320-1.c @@ -0,0 +1,23 @@ +/* PR c/5354 */ +/* Verify that GCC preserves relevant stack slots. */ + +extern void abort(void); +extern void exit(int); + +struct large { int x, y[9]; }; + +int main() +{ + int fixed; + + fixed = ({ int temp1 = 2; temp1; }) - ({ int temp2 = 1; temp2; }); + if (fixed != 1) + abort(); + + fixed = ({ struct large temp3; temp3.x = 2; temp3; }).x + - ({ struct large temp4; temp4.x = 1; temp4; }).x; + if (fixed != 1) + abort(); + + exit(0); +} |