Skip to content

Commit

Permalink
[Sema] Add implicit members even for invalid CXXRecordDecls
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ilya-biryukov committed Feb 2, 2018
1 parent ad089fe commit 659cffe
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 3 deletions.
6 changes: 3 additions & 3 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
9 changes: 9 additions & 0 deletions clang/test/Index/Inputs/crash-preamble-classes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
struct Incomplete;

struct X : Incomplete {
X();
};

struct Y : X {
using X::X;
};
8 changes: 8 additions & 0 deletions clang/test/Index/crash-preamble-classes.cpp
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 659cffe

Please sign in to comment.