diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 9 | ||||
-rw-r--r-- | clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp | 9 |
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'}} + }); + } +} |