[C++ PATCH] Fix ice-on-invalid (i ? j : k) = (void) bar (); (PR c++/30847)

Jakub Jelinek jakub@redhat.com
Mon Mar 19 17:46:00 GMT 2007


Hi!

stabilize_expr can't be called on expr with void type and side-effects
as build_target_expr_with_type asserts it isn't called with void type.
We can either work around this:
-
-	rhs = stabilize_expr (rhs, &preeval);
+	tree secondrhs;
+
+	if (VOID_TYPE_P (TREE_TYPE (rhs)) && TREE_SIDE_EFFECTS (rhs))
+	  secondrhs = fold_convert (void_type_node, integer_zero_node);
+	else
+	  secondrhs = rhs = stabilize_expr (rhs, &preeval);

        /* Check this here to avoid odd errors when trying to convert
           a throw to the type of the COND_EXPR.  */
        if (!lvalue_or_else (lhs, lv_assign))
          return error_mark_node;

        cond = build_conditional_expr
          (TREE_OPERAND (lhs, 0),
           build_modify_expr (TREE_OPERAND (lhs, 1),
                              modifycode, rhs),
           build_modify_expr (TREE_OPERAND (lhs, 2),
-                             modifycode, rhs));
+			      modifycode, secondrhs));
(side effects would be evaluated just once and as rhs has void type,
(void) 0 can be used too), or simply error out as I believe the recursive
build_modify_expr's will error out anyway with the same error message
(only difference will be that with the above pseudo-patch approach
you get 2 errors but only one with the one patch below.

Tested on x86_64, ok for 4.1/4.2/trunk?

2007-03-19  Jakub Jelinek  <jakub@redhat.com>

	PR c++/30847
	* typeck.c (build_modify_expr): Don't call stabilize_expr on RHS
	if RHS has void type.

	* g++.dg/parse/cond3.C: New test.

--- gcc/cp/typeck.c.jj	2007-03-12 17:18:01.000000000 +0100
+++ gcc/cp/typeck.c	2007-03-19 17:18:30.000000000 +0100
@@ -5708,6 +5708,12 @@ build_modify_expr (tree lhs, enum tree_c
 	tree cond;
 	tree preeval = NULL_TREE;
 
+	if (VOID_TYPE_P (TREE_TYPE (rhs)))
+	  {
+	    error ("void value not ignored as it ought to be");
+	    return error_mark_node;
+	  }
+
 	rhs = stabilize_expr (rhs, &preeval);
 
 	/* Check this here to avoid odd errors when trying to convert
--- gcc/testsuite/g++.dg/parse/cond3.C.jj	2007-03-19 17:29:12.000000000 +0100
+++ gcc/testsuite/g++.dg/parse/cond3.C	2007-03-19 17:33:54.000000000 +0100
@@ -0,0 +1,15 @@
+// PR c++/30847
+// { dg-do compile }
+// { dg-options "" }
+
+int j, k, l;
+extern void baz ();
+
+void
+foo (int i)
+{
+  (i ? j : k) = ({ l++; (void) l; });	// { dg-error "void value not ignored" }
+  (i ? j : k) += ({ l++; (void) l; });	// { dg-error "void value not ignored" }
+  (i ? j : k) = baz ();			// { dg-error "void value not ignored" }
+  (i ? j : k) *= baz ();		// { dg-error "void value not ignored" }
+}

	Jakub



More information about the Gcc-patches mailing list