]> granicus.if.org Git - clang/commitdiff
Fix regression in r197623: only diagnose a by-copy capture of an incomplete
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 21 Jan 2014 23:27:46 +0000 (23:27 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 21 Jan 2014 23:27:46 +0000 (23:27 +0000)
type if the capture is, actually, by copy.

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

lib/Sema/SemaExpr.cpp
test/SemaCXX/lambda-expressions.cpp

index 4d3eba73d78ac68fb21ba17174fc6029075cf547..3640c5ad24b81e1812d5a5715f248488c90d9a2a 100644 (file)
@@ -11660,15 +11660,6 @@ static ExprResult addAsFieldToClosureType(Sema &S,
                                   bool RefersToEnclosingLocal) {
   CXXRecordDecl *Lambda = LSI->Lambda;
 
-  // Make sure that by-copy captures are of a complete type.
-  if (!DeclRefType->isDependentType() &&
-      !DeclRefType->isReferenceType() &&
-      S.RequireCompleteType(Loc, DeclRefType,
-                            diag::err_capture_of_incomplete_type,
-                            Var->getDeclName())) {
-    return ExprError();
-  }
-
   // Build the non-static data member.
   FieldDecl *Field
     = FieldDecl::Create(S.Context, Lambda, Loc, Loc, 0, FieldType,
@@ -11844,9 +11835,18 @@ static bool captureInLambda(LambdaScopeInfo *LSI,
       return false;
     }
 
-    if (S.RequireNonAbstractType(Loc, CaptureType,
-                                 diag::err_capture_of_abstract_type))
-      return false;
+    // Make sure that by-copy captures are of a complete and non-abstract type.
+    if (BuildAndDiagnose) {
+      if (!CaptureType->isDependentType() &&
+          S.RequireCompleteType(Loc, CaptureType,
+                                diag::err_capture_of_incomplete_type,
+                                Var->getDeclName()))
+        return false;
+
+      if (S.RequireNonAbstractType(Loc, CaptureType,
+                                   diag::err_capture_of_abstract_type))
+        return false;
+    }
   }
 
   // Capture this variable in the lambda.
index 51e43216deaa86ea6174da3f8989e280b2717d1d..28a2a744f505dc54cbd915ea5ef97818116692ca 100644 (file)
@@ -294,3 +294,33 @@ namespace NSDMIs_in_lambdas {
   auto y = [&]{ struct S { int n, m = n; }; };
   void g() { auto z = [&]{ struct S { int n, m = n; }; }; }
 }
+
+namespace CaptureIncomplete {
+  struct Incomplete; // expected-note 2{{forward decl}}
+  void g(const Incomplete &a);
+  void f(Incomplete &a) {
+    (void) [a] {}; // expected-error {{incomplete}}
+    (void) [&a] {};
+
+    (void) [=] { g(a); }; // expected-error {{incomplete}}
+    (void) [&] { f(a); };
+  }
+}
+
+namespace CaptureAbstract {
+  struct S {
+    virtual void f() = 0; // expected-note {{unimplemented}}
+    int n = 0;
+  };
+  struct T : S {
+    constexpr T() {}
+    void f();
+  };
+  void f() {
+    constexpr T t = T();
+    S &s = const_cast<T&>(t);
+    // FIXME: Once we properly compute odr-use per DR712, this should be
+    // accepted (and should not capture 's').
+    [=] { return s.n; }; // expected-error {{abstract}}
+  }
+}