[PATCH] D21176: Mark invalid RecordDecls as completed.

Erik Verbruggen via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 9 03:57:53 PDT 2016


erikjv created this revision.
erikjv added a reviewer: rsmith.
erikjv added a subscriber: cfe-commits.

Sema::ActOnTag creates TagDecls for records. However, if those record
declarations are invalid, and the parser is in C++ mode, it would
silently drop the TagDecl (and leave it as "beingDefined"). The problem
is that other code (e.g. the ASTWriter) will serialize all types, and
expects them to be complete. So, leaving them open would result in
failing asserts.

Fixes PR20320


http://reviews.llvm.org/D21176

Files:
  lib/Sema/SemaDecl.cpp
  test/Index/pr20320.cpp
  test/Index/pr20320.h
  test/SemaCXX/conversion-function.cpp

Index: test/SemaCXX/conversion-function.cpp
===================================================================
--- test/SemaCXX/conversion-function.cpp
+++ test/SemaCXX/conversion-function.cpp
@@ -434,8 +434,12 @@
   struct A {
     operator enum E { e } (); // expected-error {{'PR18234::A::E' cannot be defined in a type specifier}}
     operator struct S { int n; } (); // expected-error {{'PR18234::A::S' cannot be defined in a type specifier}}
+    // expected-note at -1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'struct A' to 'const PR18234::A::S &' for 1st argument}}
+#if __cplusplus >= 201103L
+  // expected-note at -3 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'struct A' to 'PR18234::A::S &&' for 1st argument}}
+#endif
   } a;
-  A::S s = a;
+  A::S s = a; // expected-error {{no viable conversion from 'struct A' to 'A::S'}}
   A::E e = a; // expected-note {{here}}
   bool k1 = e == A::e; // expected-error {{no member named 'e'}}
   bool k2 = e.n == 0;
Index: test/Index/pr20320.h
===================================================================
--- /dev/null
+++ test/Index/pr20320.h
@@ -0,0 +1,14 @@
+#ifndef pr20320_h
+#define pr20320_h
+
+template<>
+struct S< ::Number::One>
+{
+};
+
+template<>
+struct S< ::Number::Two>
+{
+};
+
+#endif
Index: test/Index/pr20320.cpp
===================================================================
--- /dev/null
+++ test/Index/pr20320.cpp
@@ -0,0 +1,2 @@
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 local -x c++ %s
+#include "pr20320.h"
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -13065,7 +13065,14 @@
   OwnedDecl = true;
   // In C++, don't return an invalid declaration. We can't recover well from
   // the cases where we make the type anonymous.
-  return (Invalid && getLangOpts().CPlusPlus) ? nullptr : New;
+  if (Invalid && getLangOpts().CPlusPlus) {
+    if (New->isBeingDefined())
+      if (auto RD = dyn_cast<RecordDecl>(New))
+        RD->completeDefinition();
+    return nullptr;
+  } else {
+    return New;
+  }
 }
 
 void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21176.60152.patch
Type: text/x-patch
Size: 2295 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160609/eb2a3086/attachment-0001.bin>


More information about the cfe-commits mailing list