forked from OSchip/llvm-project
Fix a bug reduced from a crash when trying to use modules with libc++. We check
the linkage of functions and variables while merging declarations from modules, and we don't necessarily have enough of the rest of the AST loaded at that point to allow us to compute linkage, so serialize it instead. llvm-svn: 174943
This commit is contained in:
parent
277775b8af
commit
8858159fb5
|
@ -610,11 +610,8 @@ void NamedDecl::ClearLinkageCache() {
|
|||
}
|
||||
|
||||
Linkage NamedDecl::getLinkage() const {
|
||||
if (HasCachedLinkage) {
|
||||
assert(Linkage(CachedLinkage) ==
|
||||
getLVForDecl(this, true).linkage());
|
||||
if (HasCachedLinkage)
|
||||
return Linkage(CachedLinkage);
|
||||
}
|
||||
|
||||
CachedLinkage = getLVForDecl(this, true).linkage();
|
||||
HasCachedLinkage = 1;
|
||||
|
|
|
@ -526,6 +526,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
|
|||
FD->HasImplicitReturnZero = Record[Idx++];
|
||||
FD->IsConstexpr = Record[Idx++];
|
||||
FD->HasSkippedBody = Record[Idx++];
|
||||
FD->HasCachedLinkage = true;
|
||||
FD->CachedLinkage = Record[Idx++];
|
||||
FD->EndRangeLoc = ReadSourceLocation(Record, Idx);
|
||||
|
||||
switch ((FunctionDecl::TemplatedKind)Record[Idx++]) {
|
||||
|
@ -908,6 +910,8 @@ void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
|
|||
VD->VarDeclBits.CXXForRangeDecl = Record[Idx++];
|
||||
VD->VarDeclBits.ARCPseudoStrong = Record[Idx++];
|
||||
VD->VarDeclBits.IsConstexpr = Record[Idx++];
|
||||
VD->HasCachedLinkage = true;
|
||||
VD->CachedLinkage = Record[Idx++];
|
||||
|
||||
// Only true variables (not parameters or implicit parameters) can be merged.
|
||||
if (VD->getKind() == Decl::Var)
|
||||
|
|
|
@ -330,6 +330,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
|
|||
Record.push_back(D->hasImplicitReturnZero());
|
||||
Record.push_back(D->isConstexpr());
|
||||
Record.push_back(D->HasSkippedBody);
|
||||
Record.push_back(D->getLinkage());
|
||||
Writer.AddSourceLocation(D->getLocEnd(), Record);
|
||||
|
||||
Record.push_back(D->getTemplatedKind());
|
||||
|
@ -682,6 +683,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
|
|||
Record.push_back(D->isCXXForRangeDecl());
|
||||
Record.push_back(D->isARCPseudoStrong());
|
||||
Record.push_back(D->isConstexpr());
|
||||
Record.push_back(D->getLinkage());
|
||||
|
||||
if (D->getInit()) {
|
||||
Record.push_back(!D->isInitKnownICE() ? 1 : (D->isInitICE() ? 3 : 2));
|
||||
|
@ -1505,6 +1507,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
|
|||
Abv->Add(BitCodeAbbrevOp(0)); // isCXXForRangeDecl
|
||||
Abv->Add(BitCodeAbbrevOp(0)); // isARCPseudoStrong
|
||||
Abv->Add(BitCodeAbbrevOp(0)); // isConstexpr
|
||||
Abv->Add(BitCodeAbbrevOp(0)); // Linkage
|
||||
Abv->Add(BitCodeAbbrevOp(0)); // HasInit
|
||||
Abv->Add(BitCodeAbbrevOp(0)); // HasMemberSpecializationInfo
|
||||
// ParmVarDecl
|
||||
|
@ -1584,6 +1587,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
|
|||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong
|
||||
Abv->Add(BitCodeAbbrevOp(0)); // isConstexpr
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Linkage
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasInit
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasMemberSpecInfo
|
||||
// Type Source Info
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
// Reduced from a crash encountered with a modularized libc++, where
|
||||
// we would try to compute the linkage of a declaration before we
|
||||
// finish loading the relevant pieces of it.
|
||||
inline namespace D {
|
||||
template<class>
|
||||
struct U {
|
||||
friend bool f(const U &);
|
||||
};
|
||||
|
||||
template class U<int>;
|
||||
}
|
|
@ -179,3 +179,7 @@ module cxx_many_overloads {
|
|||
module cxx_inline_namespace {
|
||||
header "cxx-inline-namespace.h"
|
||||
}
|
||||
|
||||
module cxx_linkage_cache {
|
||||
header "cxx-linkage-cache.h"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11
|
||||
|
||||
@import cxx_linkage_cache;
|
||||
|
||||
T x; // expected-error {{unknown type name 'T'}}
|
||||
D::U<int> u;
|
||||
bool b = f(u);
|
Loading…
Reference in New Issue