summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Trieu <rtrieu@google.com>2014-09-02 19:32:44 +0000
committerRichard Trieu <rtrieu@google.com>2014-09-02 19:32:44 +0000
commitb292604553a406ff4221535e874f2c8489a5526b (patch)
treec3e33a13f8ede72debe62f1bfc0535b9a0019fc2
parent637cb90ba832a3d51cd04db87b6c34b934f51529 (diff)
downloadbcm5719-llvm-b292604553a406ff4221535e874f2c8489a5526b.tar.gz
bcm5719-llvm-b292604553a406ff4221535e874f2c8489a5526b.zip
Don't allow lambdas to capture invalid decls during template instantiations.
Fixes PR20731. llvm-svn: 216936
-rw-r--r--clang/lib/Sema/TreeTransform.h2
-rw-r--r--clang/test/SemaCXX/lambda-expressions.cpp50
2 files changed, 51 insertions, 1 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index f339d507018..3c3628a0f26 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -9085,7 +9085,7 @@ TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E,
VarDecl *CapturedVar
= cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
C->getCapturedVar()));
- if (!CapturedVar) {
+ if (!CapturedVar || CapturedVar->isInvalidDecl()) {
Invalid = true;
continue;
}
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index 9a53e4604f7..d0fe0580c91 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/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 <class L, int X = sizeof(L)>
+void Job(L l);
+
+template <typename... Args>
+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 <typename T>
+struct A {
+ T t;
+ // expected-error@-1 {{field has incomplete type 'void'}}
+};
+
+template <typename F>
+void g(F f) {
+ auto a = A<decltype(f())>{};
+ // expected-note@-1 {{in instantiation of template class 'PR20731::A<void>' 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 <class _Rp> struct function {
+ template <class _Fp>
+ function(_Fp) {
+ static_assert(sizeof(_Fp) > 0, "Type must be complete.");
+ }
+};
+
+template <typename T> void p(T t) {
+ auto l = some_undefined_function(t);
+ // expected-error@-1 {{use of undeclared identifier 'some_undefined_function'}}
+ function<void()>(([l]() {}));
+}
+void q() { p(0); }
+// expected-note@-1 {{in instantiation of function template specialization 'PR20731::p<int>' requested here}}
+}
OpenPOWER on IntegriCloud