]> granicus.if.org Git - clang/commitdiff
Don't allow lambdas to capture invalid decls during template instantiations.
authorRichard Trieu <rtrieu@google.com>
Tue, 2 Sep 2014 19:32:44 +0000 (19:32 +0000)
committerRichard Trieu <rtrieu@google.com>
Tue, 2 Sep 2014 19:32:44 +0000 (19:32 +0000)
Fixes PR20731.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216936 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/TreeTransform.h
test/SemaCXX/lambda-expressions.cpp

index f339d5070182e17b110c0a1f2bf8d8ea36e40782..3c3628a0f260a0ec352c5836ad5c8b7dee5f7e4a 100644 (file)
@@ -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;
     }
index 9a53e4604f76341909e472b2a3d37c6af0e867c2..d0fe0580c91edc007dc57b6b06e5b2f22236f174 100644 (file)
@@ -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}}
+}