This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] for PR12223
- From: Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Cc: schwab at suse dot de
- Date: Sun, 14 Sep 2003 00:08:49 +0200
- Subject: [PATCH] for PR12223
Hello,
first a bit reduced testcase:
#include <vector>
long *array;
long *val;
void insert (const std::vector <int> &siblings)
{
array[siblings[0]] = val ? 0 : 1;
}
This is misscompiled into an infinite loop. It works this way:
let lhs = array[siblings[0]]. The assignment is translated into
(lhs, val != 0) ? (lhs = 0) : (lhs1 = 1);
where lhs1 is lhs with function calls unshared (I'm not really sure why
this is done, since the comments on that place are not very
informative).
The problem is that lhs in the condition and then branch are shared; when
the [] operator is inlined, lhs becomes something like
({...; goto bla; bla: ; ...})
During tree->rtl expansions, the jumps to bla are all directed to the
copy of lhs in condition, thus creating the infinite cycle.
The patch below fixes this by unsharing the lhs.
Zdenek
* cp/typeck.c (build_modify_expr): Unshare lhs in set from
COND_EXPR.
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.436.2.15
diff -c -3 -p -r1.436.2.15 typeck.c
*** cp/typeck.c 7 Sep 2003 20:53:13 -0000 1.436.2.15
--- cp/typeck.c 13 Sep 2003 21:50:23 -0000
*************** build_modify_expr (lhs, modifycode, rhs)
*** 5525,5535 ****
else
{
tree result_type = TREE_TYPE (newrhs);
/* We have to convert each arm to the proper type because the
types may have been munged by constant folding. */
result
= build (COND_EXPR, result_type, cond,
! build_modify_expr (lhs, modifycode,
cp_convert (result_type,
TREE_OPERAND (newrhs, 1))),
build_modify_expr (lhs1, modifycode,
--- 5525,5544 ----
else
{
tree result_type = TREE_TYPE (newrhs);
+ tree lhs2;
+
+ /* Ensure that the calls are not shared with the lhs kept
+ at condition. */
+ if (TREE_SIDE_EFFECTS (lhs))
+ lhs2 = break_out_calls (lhs);
+ else
+ lhs2 = lhs;
+
/* We have to convert each arm to the proper type because the
types may have been munged by constant folding. */
result
= build (COND_EXPR, result_type, cond,
! build_modify_expr (lhs2, modifycode,
cp_convert (result_type,
TREE_OPERAND (newrhs, 1))),
build_modify_expr (lhs1, modifycode,