This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix ice-on-invalid (i ? j : k) = (void) bar (); (PR c++/30847)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 19 Mar 2007 12:06:44 -0500
- Subject: [C++ PATCH] Fix ice-on-invalid (i ? j : k) = (void) bar (); (PR c++/30847)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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