Message ID | 20180102210306.GW1833@tucnak |
---|---|
State | New |
Headers | show |
Series | [C++] Avoid NOP_EXPRs with error_mark_node operand (PR c++/83634) | expand |
On 01/02/2018 04:03 PM, Jakub Jelinek wrote: > Hi! > > The gimplifier uses in several places STRIP_USELESS_TYPE_CONVERSION and > that, being primarily a middle-end predicate, doesn't like error_mark_nodes > appearing in conversion operands. I've talked about it with Richi on IRC > and he'd prefer not to change it. > 2018-01-02 Jakub Jelinek <jakub@redhat.com> > > PR c++/83634 > * cp-gimplify.c (cp_fold) <case NOP_EXPR>: If the operand folds to > error_mark_node, return error_mark_node. > > * g++.dg/parse/pr83634.C: New test. > ok thanks
--- gcc/cp/cp-gimplify.c.jj 2017-12-14 21:11:40.616124411 +0100 +++ gcc/cp/cp-gimplify.c 2018-01-02 13:23:51.946128057 +0100 @@ -2112,7 +2112,20 @@ cp_fold (tree x) case NON_LVALUE_EXPR: if (VOID_TYPE_P (TREE_TYPE (x))) - return x; + { + /* This is just to make sure we don't end up with casts to + void from error_mark_node. If we just return x, then + cp_fold_r might fold the operand into error_mark_node and + leave the conversion in the IR. STRIP_USELESS_TYPE_CONVERSION + during gimplification doesn't like such casts. + Don't create a new tree if op0 != TREE_OPERAND (x, 0), the + folding of the operand should be in the caches and if in cp_fold_r + it will modify it in place. */ + op0 = cp_fold (TREE_OPERAND (x, 0)); + if (op0 == error_mark_node) + x = error_mark_node; + break; + } loc = EXPR_LOCATION (x); op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops); --- gcc/testsuite/g++.dg/parse/pr83634.C.jj 2018-01-02 12:39:44.500517833 +0100 +++ gcc/testsuite/g++.dg/parse/pr83634.C 2018-01-02 12:35:17.399462088 +0100 @@ -0,0 +1,11 @@ +// PR c++/83634 +// { dg-do compile } + +void +foo () +{ + const int x = fn (); // { dg-error "was not declared in this scope" } + short n; + for (n = x; n < 100; ++n) + ; +}