[CrossTU] Handle case when no USR could be generated during Decl search.
Summary: When searching for a declaration to be loaded the "lookup name" for every other Decl is computed. If the USR can not be determined here should be not an assert, instead skip this Decl. Reviewers: martong Reviewed By: martong Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D65445 llvm-svn: 368020
This commit is contained in:
parent
56bdb0c508
commit
4e79097dc7
|
@ -17,6 +17,7 @@
|
|||
#include "clang/AST/ASTImporterSharedState.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
@ -159,7 +160,7 @@ public:
|
|||
ASTUnit *Unit);
|
||||
|
||||
/// Get a name to identify a named decl.
|
||||
static std::string getLookupName(const NamedDecl *ND);
|
||||
static llvm::Optional<std::string> getLookupName(const NamedDecl *ND);
|
||||
|
||||
/// Emit diagnostics for the user for potential configuration errors.
|
||||
void emitCrossTUDiagnostics(const IndexError &IE);
|
||||
|
|
|
@ -193,12 +193,13 @@ CrossTranslationUnitContext::CrossTranslationUnitContext(CompilerInstance &CI)
|
|||
|
||||
CrossTranslationUnitContext::~CrossTranslationUnitContext() {}
|
||||
|
||||
std::string CrossTranslationUnitContext::getLookupName(const NamedDecl *ND) {
|
||||
llvm::Optional<std::string>
|
||||
CrossTranslationUnitContext::getLookupName(const NamedDecl *ND) {
|
||||
SmallString<128> DeclUSR;
|
||||
bool Ret = index::generateUSRForDecl(ND, DeclUSR);
|
||||
(void)Ret;
|
||||
assert(!Ret && "Unable to generate USR");
|
||||
return DeclUSR.str();
|
||||
if (Ret)
|
||||
return {};
|
||||
return std::string(DeclUSR.str());
|
||||
}
|
||||
|
||||
/// Recursively visits the decls of a DeclContext, and returns one with the
|
||||
|
@ -218,7 +219,8 @@ CrossTranslationUnitContext::findDefInDeclContext(const DeclContext *DC,
|
|||
const T *ResultDecl;
|
||||
if (!ND || !hasBodyOrInit(ND, ResultDecl))
|
||||
continue;
|
||||
if (getLookupName(ResultDecl) != LookupName)
|
||||
llvm::Optional<std::string> ResultLookupName = getLookupName(ResultDecl);
|
||||
if (!ResultLookupName || *ResultLookupName != LookupName)
|
||||
continue;
|
||||
return ResultDecl;
|
||||
}
|
||||
|
@ -233,12 +235,12 @@ llvm::Expected<const T *> CrossTranslationUnitContext::getCrossTUDefinitionImpl(
|
|||
assert(!hasBodyOrInit(D) &&
|
||||
"D has a body or init in current translation unit!");
|
||||
++NumGetCTUCalled;
|
||||
const std::string LookupName = getLookupName(D);
|
||||
if (LookupName.empty())
|
||||
const llvm::Optional<std::string> LookupName = getLookupName(D);
|
||||
if (!LookupName)
|
||||
return llvm::make_error<IndexError>(
|
||||
index_error_code::failed_to_generate_usr);
|
||||
llvm::Expected<ASTUnit *> ASTUnitOrError =
|
||||
loadExternalAST(LookupName, CrossTUDir, IndexName, DisplayCTUProgress);
|
||||
loadExternalAST(*LookupName, CrossTUDir, IndexName, DisplayCTUProgress);
|
||||
if (!ASTUnitOrError)
|
||||
return ASTUnitOrError.takeError();
|
||||
ASTUnit *Unit = *ASTUnitOrError;
|
||||
|
@ -294,7 +296,7 @@ llvm::Expected<const T *> CrossTranslationUnitContext::getCrossTUDefinitionImpl(
|
|||
}
|
||||
|
||||
TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
|
||||
if (const T *ResultDecl = findDefInDeclContext<T>(TU, LookupName))
|
||||
if (const T *ResultDecl = findDefInDeclContext<T>(TU, *LookupName))
|
||||
return importDefinition(ResultDecl, Unit);
|
||||
return llvm::make_error<IndexError>(index_error_code::failed_import);
|
||||
}
|
||||
|
|
|
@ -131,3 +131,17 @@ union U {
|
|||
const unsigned int b;
|
||||
};
|
||||
U extU = {.a = 4};
|
||||
|
||||
class TestAnonUnionUSR {
|
||||
public:
|
||||
inline float f(int value) {
|
||||
union {
|
||||
float f;
|
||||
int i;
|
||||
};
|
||||
i = value;
|
||||
return f;
|
||||
}
|
||||
static const int Test;
|
||||
};
|
||||
const int TestAnonUnionUSR::Test = 5;
|
||||
|
|
|
@ -25,3 +25,4 @@ c:@extSCN ctu-other.cpp.ast
|
|||
c:@extSubSCN ctu-other.cpp.ast
|
||||
c:@extSCC ctu-other.cpp.ast
|
||||
c:@extU ctu-other.cpp.ast
|
||||
c:@S@TestAnonUnionUSR@Test ctu-other.cpp.ast
|
||||
|
|
|
@ -112,6 +112,19 @@ void test_virtual_functions(mycls* obj) {
|
|||
clang_analyzer_eval(obj->fvcl(1) == 8); // expected-warning{{FALSE}} expected-warning{{TRUE}}
|
||||
}
|
||||
|
||||
class TestAnonUnionUSR {
|
||||
public:
|
||||
inline float f(int value) {
|
||||
union {
|
||||
float f;
|
||||
int i;
|
||||
};
|
||||
i = value;
|
||||
return f;
|
||||
}
|
||||
static const int Test;
|
||||
};
|
||||
|
||||
int main() {
|
||||
clang_analyzer_eval(f(3) == 2); // expected-warning{{TRUE}}
|
||||
clang_analyzer_eval(f(4) == 3); // expected-warning{{TRUE}}
|
||||
|
@ -144,4 +157,5 @@ int main() {
|
|||
clang_analyzer_eval(extSubSCN.a == 1); // expected-warning{{TRUE}}
|
||||
// clang_analyzer_eval(extSCC.a == 7); // TODO
|
||||
clang_analyzer_eval(extU.a == 4); // expected-warning{{TRUE}}
|
||||
clang_analyzer_eval(TestAnonUnionUSR::Test == 5); // expected-warning{{TRUE}}
|
||||
}
|
||||
|
|
|
@ -41,3 +41,10 @@ union U {
|
|||
};
|
||||
U u = {.a = 6};
|
||||
// CHECK-DAG: c:@u
|
||||
|
||||
// No USR can be generated for this.
|
||||
// Check for no crash in this case.
|
||||
static union {
|
||||
float uf;
|
||||
const int ui;
|
||||
};
|
||||
|
|
|
@ -76,7 +76,12 @@ void MapExtDefNamesConsumer::handleDecl(const Decl *D) {
|
|||
|
||||
void MapExtDefNamesConsumer::addIfInMain(const DeclaratorDecl *DD,
|
||||
SourceLocation defStart) {
|
||||
std::string LookupName = CrossTranslationUnitContext::getLookupName(DD);
|
||||
llvm::Optional<std::string> LookupName =
|
||||
CrossTranslationUnitContext::getLookupName(DD);
|
||||
if (!LookupName)
|
||||
return;
|
||||
assert(!LookupName->empty() && "Lookup name should be non-empty.");
|
||||
|
||||
if (CurrentFileName.empty()) {
|
||||
CurrentFileName =
|
||||
SM.getFileEntryForID(SM.getMainFileID())->tryGetRealPathName();
|
||||
|
@ -89,7 +94,7 @@ void MapExtDefNamesConsumer::addIfInMain(const DeclaratorDecl *DD,
|
|||
case VisibleNoLinkage:
|
||||
case UniqueExternalLinkage:
|
||||
if (SM.isInMainFile(defStart))
|
||||
Index[LookupName] = CurrentFileName;
|
||||
Index[*LookupName] = CurrentFileName;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue