From: Richard Smith Date: Tue, 21 Jan 2014 23:27:46 +0000 (+0000) Subject: Fix regression in r197623: only diagnose a by-copy capture of an incomplete X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8b969a8b07d34318c16362dc25e3502ba085aaf9;p=clang Fix regression in r197623: only diagnose a by-copy capture of an incomplete 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 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 4d3eba73d7..3640c5ad24 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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. diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp index 51e43216de..28a2a744f5 100644 --- a/test/SemaCXX/lambda-expressions.cpp +++ b/test/SemaCXX/lambda-expressions.cpp @@ -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); + // FIXME: Once we properly compute odr-use per DR712, this should be + // accepted (and should not capture 's'). + [=] { return s.n; }; // expected-error {{abstract}} + } +}