From: Richard Trieu Date: Tue, 2 Sep 2014 19:32:44 +0000 (+0000) Subject: Don't allow lambdas to capture invalid decls during template instantiations. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9ce674a9d0ebf833cfbb94a6cc8e8bcb5e469ff3;p=clang Don't allow lambdas to capture invalid decls during template instantiations. Fixes PR20731. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216936 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index f339d50701..3c3628a0f2 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -9085,7 +9085,7 @@ TreeTransform::TransformLambdaScope(LambdaExpr *E, VarDecl *CapturedVar = cast_or_null(getDerived().TransformDecl(C->getLocation(), C->getCapturedVar())); - if (!CapturedVar) { + if (!CapturedVar || CapturedVar->isInvalidDecl()) { Invalid = true; continue; } diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp index 9a53e4604f..d0fe0580c9 100644 --- a/test/SemaCXX/lambda-expressions.cpp +++ b/test/SemaCXX/lambda-expressions.cpp @@ -363,3 +363,53 @@ namespace PR18473 { void PR19249() { auto x = [&x]{}; // expected-error {{cannot appear in its own init}} } + +namespace PR20731 { +template +void Job(L l); + +template +void Logger(Args &&... args) { + auto len = Invalid_Function((args)...); + // expected-error@-1 {{use of undeclared identifier 'Invalid_Function'}} + Job([len]() {}); +} + +void GetMethod() { + Logger(); + // expected-note@-1 {{in instantiation of function template specialization 'PR20731::Logger<>' requested here}} +} + +template +struct A { + T t; + // expected-error@-1 {{field has incomplete type 'void'}} +}; + +template +void g(F f) { + auto a = A{}; + // expected-note@-1 {{in instantiation of template class 'PR20731::A' requested here}} + auto xf = [a, f]() {}; + int x = sizeof(xf); +}; +void f() { + g([] {}); + // expected-note-re@-1 {{in instantiation of function template specialization 'PR20731::g<(lambda at {{.*}}>' requested here}} +} + +template struct function { + template + function(_Fp) { + static_assert(sizeof(_Fp) > 0, "Type must be complete."); + } +}; + +template void p(T t) { + auto l = some_undefined_function(t); + // expected-error@-1 {{use of undeclared identifier 'some_undefined_function'}} + function(([l]() {})); +} +void q() { p(0); } +// expected-note@-1 {{in instantiation of function template specialization 'PR20731::p' requested here}} +}