From: Eric Botcazou Date: Thu, 21 Mar 2002 09:39:18 +0000 (+0000) Subject: re PR c/5354 (function call with two statement expressions yields incorrect result) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=312687cfa88b0e5ee2600e0349bf285b826521b9;p=gcc.git 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 From-SVN: r51121 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0a06dbd1b20..56349e57fad 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2002-03-21 Eric Botcazou + Richard Henderson + + PR c/5354 + * c-common.c (c_expand_expr): Preserve result of a statement + expression if needed. + 2002-03-21 Jakub Jelinek PR bootstrap/4195 diff --git a/gcc/c-common.c b/gcc/c-common.c index 91f2a20476b..28920599dea 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 00000000000..05f72c65482 --- /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); +}