summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Biryukov <ibiryukov@google.com>2018-02-02 08:40:08 +0000
committerIlya Biryukov <ibiryukov@google.com>2018-02-02 08:40:08 +0000
commit659cffeec4663adca85940f91a43b29e8bd038fd (patch)
treeee448d9b112f5682db6fea99430bc81259f7d895
parentad089fe46e166d006c449902bed09401a8d4a44e (diff)
downloadbcm5719-llvm-659cffeec4663adca85940f91a43b29e8bd038fd.tar.gz
bcm5719-llvm-659cffeec4663adca85940f91a43b29e8bd038fd.zip
[Sema] Add implicit members even for invalid CXXRecordDecls
Summary: 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 ShadowDecls), - lookup of its constructors was not run before ASTWriter serialized it. This may require the ShadowDecls created for inherited 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. Reviewers: bkramer Reviewed By: bkramer Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D42810 llvm-svn: 324062
-rw-r--r--clang/lib/Sema/SemaDecl.cpp6
-rw-r--r--clang/test/Index/Inputs/crash-preamble-classes.h9
-rw-r--r--clang/test/Index/crash-preamble-classes.cpp8
3 files changed, 20 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 526f6802c33..c3975f9f62d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15440,10 +15440,10 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
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.
diff --git a/clang/test/Index/Inputs/crash-preamble-classes.h b/clang/test/Index/Inputs/crash-preamble-classes.h
new file mode 100644
index 00000000000..a8fb5cede05
--- /dev/null
+++ b/clang/test/Index/Inputs/crash-preamble-classes.h
@@ -0,0 +1,9 @@
+struct Incomplete;
+
+struct X : Incomplete {
+ X();
+};
+
+struct Y : X {
+ using X::X;
+};
diff --git a/clang/test/Index/crash-preamble-classes.cpp b/clang/test/Index/crash-preamble-classes.cpp
new file mode 100644
index 00000000000..e7d4bd70aea
--- /dev/null
+++ b/clang/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
OpenPOWER on IntegriCloud