]> granicus.if.org Git - clang/commitdiff
Mark lambda decl as invalid if a captured variable has an invalid type.
authorJorge Gorbe Moya <jgorbe@google.com>
Wed, 21 Nov 2018 17:49:37 +0000 (17:49 +0000)
committerJorge Gorbe Moya <jgorbe@google.com>
Wed, 21 Nov 2018 17:49:37 +0000 (17:49 +0000)
This causes the compiler to crash when trying to compute a layout for
the lambda closure type (see included test).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@347402 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/SemaCXX/lambda-invalid-capture.cpp [new file with mode: 0644]

index 50ace940187195c52207b8611fd5ee1a2b79aa29..c9be58be9f187ef467b0b451387a7cd13b944b5c 100644 (file)
@@ -14966,6 +14966,21 @@ static void addAsFieldToClosureType(Sema &S, LambdaScopeInfo *LSI,
     = FieldDecl::Create(S.Context, Lambda, Loc, Loc, nullptr, FieldType,
                         S.Context.getTrivialTypeSourceInfo(FieldType, Loc),
                         nullptr, false, ICIS_NoInit);
+  // If the variable being captured has an invalid type, mark the lambda class
+  // as invalid as well.
+  if (!FieldType->isDependentType()) {
+    if (S.RequireCompleteType(Loc, FieldType, diag::err_field_incomplete)) {
+      Lambda->setInvalidDecl();
+      Field->setInvalidDecl();
+    } else {
+      NamedDecl *Def;
+      FieldType->isIncompleteType(&Def);
+      if (Def && Def->isInvalidDecl()) {
+        Lambda->setInvalidDecl();
+        Field->setInvalidDecl();
+      }
+    }
+  }
   Field->setImplicit(true);
   Field->setAccess(AS_private);
   Lambda->addDecl(Field);
diff --git a/test/SemaCXX/lambda-invalid-capture.cpp b/test/SemaCXX/lambda-invalid-capture.cpp
new file mode 100644 (file)
index 0000000..3234970
--- /dev/null
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// Don't crash.
+
+struct g {
+  j; // expected-error {{C++ requires a type specifier for all declarations}}
+};
+
+void captures_invalid_type() {
+  g child;
+  auto q = [child]{};
+  const int n = sizeof(q);
+}
+
+void captures_invalid_array_type() {
+  g child[100];
+  auto q = [child]{};
+  const int n = sizeof(q);
+}