Skip to content

Commit 4e79097

Browse files
committed
[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
1 parent 56bdb0c commit 4e79097

File tree

7 files changed

+56
-12
lines changed

7 files changed

+56
-12
lines changed

clang/include/clang/CrossTU/CrossTranslationUnit.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "clang/AST/ASTImporterSharedState.h"
1818
#include "clang/Basic/LLVM.h"
1919
#include "llvm/ADT/DenseMap.h"
20+
#include "llvm/ADT/Optional.h"
2021
#include "llvm/ADT/SmallPtrSet.h"
2122
#include "llvm/ADT/StringMap.h"
2223
#include "llvm/Support/Error.h"
@@ -159,7 +160,7 @@ class CrossTranslationUnitContext {
159160
ASTUnit *Unit);
160161

161162
/// Get a name to identify a named decl.
162-
static std::string getLookupName(const NamedDecl *ND);
163+
static llvm::Optional<std::string> getLookupName(const NamedDecl *ND);
163164

164165
/// Emit diagnostics for the user for potential configuration errors.
165166
void emitCrossTUDiagnostics(const IndexError &IE);

clang/lib/CrossTU/CrossTranslationUnit.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,13 @@ CrossTranslationUnitContext::CrossTranslationUnitContext(CompilerInstance &CI)
193193

194194
CrossTranslationUnitContext::~CrossTranslationUnitContext() {}
195195

196-
std::string CrossTranslationUnitContext::getLookupName(const NamedDecl *ND) {
196+
llvm::Optional<std::string>
197+
CrossTranslationUnitContext::getLookupName(const NamedDecl *ND) {
197198
SmallString<128> DeclUSR;
198199
bool Ret = index::generateUSRForDecl(ND, DeclUSR);
199-
(void)Ret;
200-
assert(!Ret && "Unable to generate USR");
201-
return DeclUSR.str();
200+
if (Ret)
201+
return {};
202+
return std::string(DeclUSR.str());
202203
}
203204

204205
/// Recursively visits the decls of a DeclContext, and returns one with the
@@ -218,7 +219,8 @@ CrossTranslationUnitContext::findDefInDeclContext(const DeclContext *DC,
218219
const T *ResultDecl;
219220
if (!ND || !hasBodyOrInit(ND, ResultDecl))
220221
continue;
221-
if (getLookupName(ResultDecl) != LookupName)
222+
llvm::Optional<std::string> ResultLookupName = getLookupName(ResultDecl);
223+
if (!ResultLookupName || *ResultLookupName != LookupName)
222224
continue;
223225
return ResultDecl;
224226
}
@@ -233,12 +235,12 @@ llvm::Expected<const T *> CrossTranslationUnitContext::getCrossTUDefinitionImpl(
233235
assert(!hasBodyOrInit(D) &&
234236
"D has a body or init in current translation unit!");
235237
++NumGetCTUCalled;
236-
const std::string LookupName = getLookupName(D);
237-
if (LookupName.empty())
238+
const llvm::Optional<std::string> LookupName = getLookupName(D);
239+
if (!LookupName)
238240
return llvm::make_error<IndexError>(
239241
index_error_code::failed_to_generate_usr);
240242
llvm::Expected<ASTUnit *> ASTUnitOrError =
241-
loadExternalAST(LookupName, CrossTUDir, IndexName, DisplayCTUProgress);
243+
loadExternalAST(*LookupName, CrossTUDir, IndexName, DisplayCTUProgress);
242244
if (!ASTUnitOrError)
243245
return ASTUnitOrError.takeError();
244246
ASTUnit *Unit = *ASTUnitOrError;
@@ -294,7 +296,7 @@ llvm::Expected<const T *> CrossTranslationUnitContext::getCrossTUDefinitionImpl(
294296
}
295297

296298
TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
297-
if (const T *ResultDecl = findDefInDeclContext<T>(TU, LookupName))
299+
if (const T *ResultDecl = findDefInDeclContext<T>(TU, *LookupName))
298300
return importDefinition(ResultDecl, Unit);
299301
return llvm::make_error<IndexError>(index_error_code::failed_import);
300302
}

clang/test/Analysis/Inputs/ctu-other.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,17 @@ union U {
131131
const unsigned int b;
132132
};
133133
U extU = {.a = 4};
134+
135+
class TestAnonUnionUSR {
136+
public:
137+
inline float f(int value) {
138+
union {
139+
float f;
140+
int i;
141+
};
142+
i = value;
143+
return f;
144+
}
145+
static const int Test;
146+
};
147+
const int TestAnonUnionUSR::Test = 5;

clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ c:@extSCN ctu-other.cpp.ast
2525
c:@extSubSCN ctu-other.cpp.ast
2626
c:@extSCC ctu-other.cpp.ast
2727
c:@extU ctu-other.cpp.ast
28+
c:@S@TestAnonUnionUSR@Test ctu-other.cpp.ast

clang/test/Analysis/ctu-main.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,19 @@ void test_virtual_functions(mycls* obj) {
112112
clang_analyzer_eval(obj->fvcl(1) == 8); // expected-warning{{FALSE}} expected-warning{{TRUE}}
113113
}
114114

115+
class TestAnonUnionUSR {
116+
public:
117+
inline float f(int value) {
118+
union {
119+
float f;
120+
int i;
121+
};
122+
i = value;
123+
return f;
124+
}
125+
static const int Test;
126+
};
127+
115128
int main() {
116129
clang_analyzer_eval(f(3) == 2); // expected-warning{{TRUE}}
117130
clang_analyzer_eval(f(4) == 3); // expected-warning{{TRUE}}
@@ -144,4 +157,5 @@ int main() {
144157
clang_analyzer_eval(extSubSCN.a == 1); // expected-warning{{TRUE}}
145158
// clang_analyzer_eval(extSCC.a == 7); // TODO
146159
clang_analyzer_eval(extU.a == 4); // expected-warning{{TRUE}}
160+
clang_analyzer_eval(TestAnonUnionUSR::Test == 5); // expected-warning{{TRUE}}
147161
}

clang/test/Analysis/func-mapping-test.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,10 @@ union U {
4141
};
4242
U u = {.a = 6};
4343
// CHECK-DAG: c:@u
44+
45+
// No USR can be generated for this.
46+
// Check for no crash in this case.
47+
static union {
48+
float uf;
49+
const int ui;
50+
};

clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,12 @@ void MapExtDefNamesConsumer::handleDecl(const Decl *D) {
7676

7777
void MapExtDefNamesConsumer::addIfInMain(const DeclaratorDecl *DD,
7878
SourceLocation defStart) {
79-
std::string LookupName = CrossTranslationUnitContext::getLookupName(DD);
79+
llvm::Optional<std::string> LookupName =
80+
CrossTranslationUnitContext::getLookupName(DD);
81+
if (!LookupName)
82+
return;
83+
assert(!LookupName->empty() && "Lookup name should be non-empty.");
84+
8085
if (CurrentFileName.empty()) {
8186
CurrentFileName =
8287
SM.getFileEntryForID(SM.getMainFileID())->tryGetRealPathName();
@@ -89,7 +94,7 @@ void MapExtDefNamesConsumer::addIfInMain(const DeclaratorDecl *DD,
8994
case VisibleNoLinkage:
9095
case UniqueExternalLinkage:
9196
if (SM.isInMainFile(defStart))
92-
Index[LookupName] = CurrentFileName;
97+
Index[*LookupName] = CurrentFileName;
9398
break;
9499
default:
95100
break;

0 commit comments

Comments
 (0)