This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]