In this testcase, the use of COUNT requires us to capture it because it's bound to a reference, but the lambda doesn't capture, so it's ill-formed. We're supposed to reject this use in mark_use, but we were getting confused by the location wrapper. This patch teaches mark_use to look through location wrappers.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 91354c9fd7f4773e2c95b36237b88c1f71657097 Author: Jason Merrill <ja...@redhat.com> Date: Fri Jun 1 23:29:10 2018 -0400 PR c++/85761 - ICE with ill-formed use of const outer variable. * expr.c (mark_use): Handle location wrappers. diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index 0d0a10ec4a6..9780b75d1cd 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -139,6 +139,9 @@ mark_use (tree expr, bool rvalue_p, bool read_p, break; } } + temp_override<location_t> l (input_location); + if (loc != UNKNOWN_LOCATION) + input_location = loc; expr = process_outer_var_ref (expr, tf_warning_or_error, true); if (!(TREE_TYPE (oexpr) && TYPE_REF_P (TREE_TYPE (oexpr)))) @@ -184,6 +187,11 @@ mark_use (tree expr, bool rvalue_p, bool read_p, } break; default: + if (location_wrapper_p (expr)) + { + loc = EXPR_LOCATION (expr); + recurse_op[0] = true; + } break; } diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const8.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const8.C new file mode 100644 index 00000000000..41cfd43b3a7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const8.C @@ -0,0 +1,19 @@ +// PR c++/85761 +// { dg-do compile { target c++11 } } + +template <typename T> +void out(const T& value); + +struct foo { + void bar(); +}; + +void foo::bar() +{ + constexpr int COUNT = 10000; + auto run = []() { + out(COUNT); // { dg-error "9:not captured" } + }; + + run(); +}