We instantiate the return type of the lambda outside of the function context, at which point trying to walk from the template instantiation context up to the context of 'f' hits NULL_TREE. So we should handle that.
There was also a SFINAE issue whereby we skipped the error in SFINAE context, but still gave the inform. Tested x86_64-pc-linux-gnu, applying to trunk.
commit 1742e12992e0df29546bde5b3714a07ec61e14c7 Author: Jason Merrill <ja...@redhat.com> Date: Wed Jan 11 07:45:01 2017 -0500 PR c++/78337 - ICE on invalid with generic lambda * semantics.c (process_outer_var_ref): Check if containing_function is null. Move inform call under complain test. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 342b671..4202475 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3278,6 +3278,8 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain) 2. a non-lambda function, or 3. a non-default capturing lambda function. */ while (context != containing_function + /* containing_function can be null with invalid generic lambdas. */ + && containing_function && LAMBDA_FUNCTION_P (containing_function)) { tree closure = DECL_CONTEXT (containing_function); @@ -3365,10 +3367,13 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain) else { if (complain & tf_error) - error (VAR_P (decl) - ? G_("use of local variable with automatic storage from containing function") - : G_("use of parameter from containing function")); - inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl); + { + error (VAR_P (decl) + ? G_("use of local variable with automatic storage from " + "containing function") + : G_("use of parameter from containing function")); + inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl); + } return error_mark_node; } return decl; diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-ice5.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-ice5.C new file mode 100644 index 0000000..473e412 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-ice5.C @@ -0,0 +1,27 @@ +// PR c++/78337 +// { dg-do compile { target c++14 } } + +struct X { + static constexpr int foo (int b) { + return b; + } +}; + +template<int> +using Void = void; + +template<typename F,typename A> +auto +bar(F f, A a) -> decltype( ( f(a) , 0 ) ) // { dg-error "no match" } +{ return {}; } + + +int main() { + //constexpr + int f = 3; + (void)f; + auto l = [](auto of_type_X)-> + Void<(decltype(of_type_X)::foo(f), 0)> // { dg-error "variable" } + {return;}; + bar(l , X{}); // { dg-error "no match" } +}