From: Balazs Keri <1.int32@gmail.com> Date: Tue, 6 Aug 2019 12:10:16 +0000 (+0000) Subject: [CrossTU] Handle case when no USR could be generated during Decl search. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7d8e55c8bbf7a15c9738a1b029717af1e5a2fb48;p=clang [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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368020 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/CrossTU/CrossTranslationUnit.h b/include/clang/CrossTU/CrossTranslationUnit.h index a712560790..bf9ee8d1a0 100644 --- a/include/clang/CrossTU/CrossTranslationUnit.h +++ b/include/clang/CrossTU/CrossTranslationUnit.h @@ -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 getLookupName(const NamedDecl *ND); /// Emit diagnostics for the user for potential configuration errors. void emitCrossTUDiagnostics(const IndexError &IE); diff --git a/lib/CrossTU/CrossTranslationUnit.cpp b/lib/CrossTU/CrossTranslationUnit.cpp index f43180a2a2..bd8a022eb4 100644 --- a/lib/CrossTU/CrossTranslationUnit.cpp +++ b/lib/CrossTU/CrossTranslationUnit.cpp @@ -193,12 +193,13 @@ CrossTranslationUnitContext::CrossTranslationUnitContext(CompilerInstance &CI) CrossTranslationUnitContext::~CrossTranslationUnitContext() {} -std::string CrossTranslationUnitContext::getLookupName(const NamedDecl *ND) { +llvm::Optional +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 ResultLookupName = getLookupName(ResultDecl); + if (!ResultLookupName || *ResultLookupName != LookupName) continue; return ResultDecl; } @@ -233,12 +235,12 @@ llvm::Expected 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 LookupName = getLookupName(D); + if (!LookupName) return llvm::make_error( index_error_code::failed_to_generate_usr); llvm::Expected 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 CrossTranslationUnitContext::getCrossTUDefinitionImpl( } TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl(); - if (const T *ResultDecl = findDefInDeclContext(TU, LookupName)) + if (const T *ResultDecl = findDefInDeclContext(TU, *LookupName)) return importDefinition(ResultDecl, Unit); return llvm::make_error(index_error_code::failed_import); } diff --git a/test/Analysis/Inputs/ctu-other.cpp b/test/Analysis/Inputs/ctu-other.cpp index a9ff6b5a93..c2410ced35 100644 --- a/test/Analysis/Inputs/ctu-other.cpp +++ b/test/Analysis/Inputs/ctu-other.cpp @@ -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; diff --git a/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt b/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt index 3df181b29d..da95098f4c 100644 --- a/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt +++ b/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt @@ -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 diff --git a/test/Analysis/ctu-main.cpp b/test/Analysis/ctu-main.cpp index 1cb0d4a9d7..aae4808e90 100644 --- a/test/Analysis/ctu-main.cpp +++ b/test/Analysis/ctu-main.cpp @@ -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}} } diff --git a/test/Analysis/func-mapping-test.cpp b/test/Analysis/func-mapping-test.cpp index f6eeb261da..5c04d9411f 100644 --- a/test/Analysis/func-mapping-test.cpp +++ b/test/Analysis/func-mapping-test.cpp @@ -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; +}; diff --git a/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp b/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp index 7a374698f7..3c015fef93 100644 --- a/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp +++ b/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp @@ -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 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;