diff mbox

[C++] Fix delayed folding caused ICE (PR c++/69211)

Message ID 20160111175036.GH18720@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Jan. 11, 2016, 5:50 p.m. UTC
Hi!

Seems since delayed C++ folding fold_* can sometimes be called with
operand(s) that are NOP_EXPR of INTEGER_CST.  Unfortunately the folder
is heavily unprepared to deal with that, I think it is not dozens but
hundreds of places where it assumes that if argN (result of STRIP_NOPS)
is INTEGER_CST then argN == opN and there is no need to fold_convert it
to type.  So it seems easier to make sure we don't do that again.
The problem is in cp_fold, where it folded both arguments, but if
any of them for COMPOUND_EXPR or MODIFY_EXPR has side effects, it
throws the folded arguments on the floor and keeps using the old thing.
While it is (probably) inappropriate to fold the whole COMPOUND_EXPR or
MODIFY_EXPR in that case, we should at least build a new COMPOUND_EXPR
or MODIFY_EXPR and stick the folded argument(s) into it.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-01-11  Jakub Jelinek  <jakub@redhat.com>

	PR c++/69211
	* cp-gimplify.c (cp_fold): If COMPOUND_EXPR or MODIFY_EXPR
	folded operands have side-effects, but folding changed any of them,
	build a new tree with the folded operands instead of returning the
	unfolded tree.

	* g++.dg/opt/pr69211.C: New test.


	Jakub

Comments

Jason Merrill Jan. 11, 2016, 5:57 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

--- gcc/cp/cp-gimplify.c.jj	2016-01-11 13:22:36.000000000 +0100
+++ gcc/cp/cp-gimplify.c	2016-01-11 15:26:46.898802115 +0100
@@ -2089,7 +2089,11 @@  cp_fold (tree x)
       if ((code == COMPOUND_EXPR || code == MODIFY_EXPR)
 	  && ((op1 && TREE_SIDE_EFFECTS (op1))
 	       || (op0 && TREE_SIDE_EFFECTS (op0))))
-	break;
+	{
+	  if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
+	    x = build2_loc (loc, code, TREE_TYPE (x), op0, op1);
+	  break;
+	}
       if (TREE_CODE (x) == COMPOUND_EXPR && !op0)
 	op0 = build_empty_stmt (loc);
 
--- gcc/testsuite/g++.dg/opt/pr69211.C.jj	2016-01-11 15:27:58.283816511 +0100
+++ gcc/testsuite/g++.dg/opt/pr69211.C	2016-01-11 15:27:41.000000000 +0100
@@ -0,0 +1,10 @@ 
+// PR c++/69211
+// { dg-do compile }
+
+int a, b;
+
+int
+foo ()
+{
+  return (a & 5UL | (b = 4, 4L)) > 4;
+}