[PATCH] D42810: [Sema] Add implicit members even for invalid CXXRecordDecls

Ilya Biryukov via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 1 11:58:22 PST 2018


ilya-biryukov created this revision.
ilya-biryukov added a reviewer: bkramer.

It should be safe, since other code paths are already generating
implicit members even in invalid CXXRecordDecls (e.g. lookup).

If we don't generate implicit members on CXXRecordDecl's completion,
they will be generated by next lookup of constructors. This causes a
crash when the following conditions are met:

- a CXXRecordDecl is invalid,
- it is provided via ExternalASTSource (e.g. from PCH),
- it has inherited constructors (they create as ShadowDecl),
- lookup of its constructors was not run before ASTWriter serialized it.

This causes the ShadowDecls created for implicit constructors to be
removed from the class, but that's no longer possible since class is
provided by ExternalASTSource.

See provided lit test for an example.


Repository:
  rC Clang

https://reviews.llvm.org/D42810

Files:
  lib/Sema/SemaDecl.cpp
  test/Index/Inputs/crash-preamble-classes.h
  test/Index/crash-preamble-classes.cpp


Index: test/Index/crash-preamble-classes.cpp
===================================================================
--- /dev/null
+++ test/Index/crash-preamble-classes.cpp
@@ -0,0 +1,8 @@
+#include "crash-preamble-classes.h"
+
+struct Z : Y {
+  Z() {}
+};
+
+// RUN: env CINDEXTEST_EDITING=1 \
+// RUN: c-index-test -test-load-source-reparse 5 local -I %S/Inputs %s
Index: test/Index/Inputs/crash-preamble-classes.h
===================================================================
--- /dev/null
+++ test/Index/Inputs/crash-preamble-classes.h
@@ -0,0 +1,9 @@
+struct Incomplete;
+
+struct X : Incomplete {
+  X();
+};
+
+struct Y : X {
+  using X::X;
+};
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -15430,10 +15430,10 @@
                                           CXXRecord->getDestructor());
         }
 
-        if (!CXXRecord->isInvalidDecl()) {
-          // Add any implicitly-declared members to this class.
-          AddImplicitlyDeclaredMembersToClass(CXXRecord);
+        // Add any implicitly-declared members to this class.
+        AddImplicitlyDeclaredMembersToClass(CXXRecord);
 
+        if (!CXXRecord->isInvalidDecl()) {
           // If we have virtual base classes, we may end up finding multiple
           // final overriders for a given virtual function. Check for this
           // problem now.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D42810.132443.patch
Type: text/x-patch
Size: 1430 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180201/1b310c4d/attachment.bin>


More information about the cfe-commits mailing list