summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2013-12-18 23:02:36 +0000
committerDouglas Gregor <dgregor@apple.com>2013-12-18 23:02:36 +0000
commitd1e3ceb5ecb9a156f45d15ae8ccdcab0deb85590 (patch)
treebbcd02b25267e507c6976cb98a3136aa14ca32c7
parent64de91522fae01c4e202e92a8b5674c13ae72ba7 (diff)
downloadbcm5719-llvm-d1e3ceb5ecb9a156f45d15ae8ccdcab0deb85590.tar.gz
bcm5719-llvm-d1e3ceb5ecb9a156f45d15ae8ccdcab0deb85590.zip
Require the type of a by-copy capture to be complete before creating its field.
The problem here is more serious than the fix implies. Adding a field to a class updates the triviality bits for the class (among other things). Failing to require a complete type before adding the field meant that these updates don't happen in the well-formed case where the capture is an uninstantiated class template specialization, leading the lambda itself to be treated as having a trivial copy constructor when it shouldn't. Fixes <rdar://problem/15560464>. llvm-svn: 197623
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/SemaExpr.cpp9
-rw-r--r--clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp9
3 files changed, 20 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9eed407f932..fc7a0082ff7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -935,6 +935,8 @@ def err_throw_abstract_type : Error<
def err_array_of_abstract_type : Error<"array of abstract class type %0">;
def err_capture_of_abstract_type : Error<
"by-copy capture of value of abstract type %0">;
+def err_capture_of_incomplete_type : Error<
+ "by-copy capture of variable %0 with incomplete type %1">;
def err_multiple_final_overriders : Error<
"virtual function %q0 has more than one final overrider in %1">;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index fcd972436da..a1de4046e0f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11617,6 +11617,15 @@ 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,
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
index 2ddcf18409e..551c100ff7a 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
@@ -100,3 +100,12 @@ namespace rdar14468891 {
[x]() {}(); // expected-error{{by-copy capture of value of abstract type 'rdar14468891::X'}}
}
}
+
+namespace rdar15560464 {
+ struct X; // expected-note{{forward declaration of 'rdar15560464::X'}}
+ void foo(const X& param) {
+ auto x = ([=]() {
+ auto& y = param; // expected-error{{by-copy capture of variable 'param' with incomplete type 'const rdar15560464::X'}}
+ });
+ }
+}
OpenPOWER on IntegriCloud