r197623 - Require the type of a by-copy capture to be complete before creating its field.

Douglas Gregor dgregor at apple.com
Wed Dec 18 15:02:37 PST 2013


Author: dgregor
Date: Wed Dec 18 17:02:36 2013
New Revision: 197623

URL: http://llvm.org/viewvc/llvm-project?rev=197623&view=rev
Log:
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>.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=197623&r1=197622&r2=197623&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Dec 18 17:02:36 2013
@@ -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">; 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=197623&r1=197622&r2=197623&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Dec 18 17:02:36 2013
@@ -11617,6 +11617,15 @@ static ExprResult addAsFieldToClosureTyp
                                   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,

Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp?rev=197623&r1=197622&r2=197623&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp Wed Dec 18 17:02:36 2013
@@ -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'}}
+      });
+  }
+}





More information about the cfe-commits mailing list