summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-01-21 23:27:46 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-01-21 23:27:46 +0000
commit111d3485af25dc8569d3a0638e55ee0d1afd88fe (patch)
tree101de57838adbaf6991bd5aa5cd658c27d7a3ab1 /clang
parent4de315430c2643447fb77e3c6e36940ce4a75aca (diff)
downloadbcm5719-llvm-111d3485af25dc8569d3a0638e55ee0d1afd88fe.tar.gz
bcm5719-llvm-111d3485af25dc8569d3a0638e55ee0d1afd88fe.zip
Fix regression in r197623: only diagnose a by-copy capture of an incomplete
type if the capture is, actually, by copy. llvm-svn: 199772
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp24
-rw-r--r--clang/test/SemaCXX/lambda-expressions.cpp30
2 files changed, 42 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 4d3eba73d78..3640c5ad24b 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/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/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index 51e43216dea..28a2a744f50 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/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&>(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}}
+ }
+}
OpenPOWER on IntegriCloud