From: Jason Merrill Date: Fri, 11 Jan 2019 22:36:20 +0000 (-0500) Subject: PR c++/88613 - ICE with use of const var in lambda. X-Git-Tag: basepoints/gcc-10~1806 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=f43e0585fab95e5cc2efac9aa26a8b74eeffbd71;p=gcc.git PR c++/88613 - ICE with use of const var in lambda. The issue here was that we were cp_folding a location wrapper around a lambda capture proxy before it had been mark_rvalue_used. I considered adding mark_rvalue_use calls to build_new_op_1, but it seems appropriate to have them in cp_fold_maybe_rvalue when we know we're trying to produce an rvalue. The change to mark_use is for a related issue: when we change the operand of the location wrapper from VAR_DECL to INTEGER_CST, we need the TREE_CODE of the location wrapper to change as well, from VIEW_CONVERT_EXPR to NON_LVALUE_EXPR. * expr.c (mark_use): Fix location wrapper handling. * cp-gimplify.c (cp_fold_maybe_rvalue): Call mark_rvalue_use. From-SVN: r267859 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5a5256f13fc5..9208f1e4937a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-01-11 Jason Merrill + + PR c++/88613 - ICE with use of const var in lambda. + * expr.c (mark_use): Fix location wrapper handling. + * cp-gimplify.c (cp_fold_maybe_rvalue): Call mark_rvalue_use. + 2019-01-11 Tobias Burnus PR C++/88114 diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 726adac4f4ee..121dfa41d8d2 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -2124,6 +2124,8 @@ cp_fold_maybe_rvalue (tree x, bool rval) while (true) { x = cp_fold (x); + if (rval) + x = mark_rvalue_use (x); if (rval && DECL_P (x) && !TYPE_REF_P (TREE_TYPE (x))) { diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index 071c6fb92056..9160043ed114 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -187,10 +187,23 @@ mark_use (tree expr, bool rvalue_p, bool read_p, } break; - CASE_CONVERT: case VIEW_CONVERT_EXPR: if (location_wrapper_p (expr)) - loc = EXPR_LOCATION (expr); + { + loc = EXPR_LOCATION (expr); + tree op = TREE_OPERAND (expr, 0); + tree nop = RECUR (op); + if (nop == error_mark_node) + return error_mark_node; + TREE_OPERAND (expr, 0) = nop; + /* If we're replacing a DECL with a constant, we also need to change + the TREE_CODE of the location wrapper. */ + if (op != nop && rvalue_p) + TREE_SET_CODE (expr, NON_LVALUE_EXPR); + return expr; + } + gcc_fallthrough(); + CASE_CONVERT: recurse_op[0] = true; break; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const10.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const10.C new file mode 100644 index 000000000000..3112f08f5c20 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const10.C @@ -0,0 +1,11 @@ +// PR c++/88613 +// { dg-do compile { target c++11 } } +// { dg-additional-options -Wtautological-compare } + +void a() { + const int b = 5; + [=] { + if (b != 5) + ; + }(); +}