This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: Fix bug 787: g++ calls function multiple times for multiple pre-increment
- To: gcc-patches at gcc dot gnu dot org
- Subject: PATCH: Fix bug 787: g++ calls function multiple times for multiple pre-increment
- From: Erik Rozendaal <dlr at acm dot org>
- Date: Sat, 07 Jul 2001 16:57:30 -0700
This patch avoids duplicating the argument to a pre- or post-increment
when used as an lvalue and when the argument has side-effects. This
fixes bug 787.
Added a test case as well (and make check-c++ works).
Erik
2001-07-01 Erik Rozendaal <dlr@acm.org>
* cp/typeck.c (unary_complex_lvalue): Do not duplicate the
argument to modify, pre-, or post-increment when used as an
lvalue and when the argument has side-effects.
Index: gcc/cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.356
diff -c -3 -p -r1.356 typeck.c
*** typeck.c 2001/07/07 01:07:22 1.356
--- typeck.c 2001/07/07 23:34:02
*************** unary_complex_lvalue (code, arg)
*** 4808,4819 ****
|| TREE_CODE (arg) == MIN_EXPR || TREE_CODE (arg) == MAX_EXPR)
return rationalize_conditional_expr (code, arg);
if (TREE_CODE (arg) == MODIFY_EXPR
|| TREE_CODE (arg) == PREINCREMENT_EXPR
|| TREE_CODE (arg) == PREDECREMENT_EXPR)
! return unary_complex_lvalue
! (code, build (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (arg, 0)),
! arg, TREE_OPERAND (arg, 0)));
if (code != ADDR_EXPR)
return 0;
--- 4808,4828 ----
|| TREE_CODE (arg) == MIN_EXPR || TREE_CODE (arg) == MAX_EXPR)
return rationalize_conditional_expr (code, arg);
+ /* Handle (a = b), (++a), and (--a) used as an "lvalue". */
if (TREE_CODE (arg) == MODIFY_EXPR
|| TREE_CODE (arg) == PREINCREMENT_EXPR
|| TREE_CODE (arg) == PREDECREMENT_EXPR)
! {
! tree lvalue = TREE_OPERAND (arg, 0);
! if (TREE_SIDE_EFFECTS (lvalue))
! {
! lvalue = stabilize_reference (lvalue);
! arg = build (TREE_CODE (arg), TREE_TYPE (arg),
! lvalue, TREE_OPERAND (arg, 1));
! }
! return unary_complex_lvalue
! (code, build (COMPOUND_EXPR, TREE_TYPE (lvalue), arg, lvalue));
! }
if (code != ADDR_EXPR)
return 0;
Index: gcc/testsuite/g++.dg/init-ref-lhs.C
===================================================================
RCS file: init-ref-lhs.C
diff -N -c -3 -p init-ref-lhs.C
*** /dev/null Fri Mar 23 20:37:44 2001
--- init-ref-lhs.C Sat Jul 7 14:50:42 2001
***************
*** 0 ****
--- 1,44 ----
+ /* Test case for GNATS bug 787. */
+ /* { dg-do run } */
+
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ static int calls;
+
+ int &foo (int &arg)
+ {
+ calls++;
+ arg=0;
+ return arg;
+ }
+
+ int &identity (int &x)
+ {
+ return x;
+ }
+
+ int main()
+ {
+ int a;
+
+ calls = 0;
+ int &b = ++foo (a);
+ if (calls > 1)
+ abort ();
+ if (&a != &b)
+ abort ();
+ if (a != 1)
+ abort ();
+
+ calls = 0;
+ int &c = ++identity (++foo (a));
+ if (calls > 1)
+ abort ();
+ if (&a != &c)
+ abort ();
+ if (a != 2)
+ abort ();
+
+ exit (0);
+ }