]> granicus.if.org Git - clang/commitdiff
[CrossTU] Handle case when no USR could be generated during Decl search.
authorBalazs Keri <1.int32@gmail.com>
Tue, 6 Aug 2019 12:10:16 +0000 (12:10 +0000)
committerBalazs Keri <1.int32@gmail.com>
Tue, 6 Aug 2019 12:10:16 +0000 (12:10 +0000)
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

include/clang/CrossTU/CrossTranslationUnit.h
lib/CrossTU/CrossTranslationUnit.cpp
test/Analysis/Inputs/ctu-other.cpp
test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt
test/Analysis/ctu-main.cpp
test/Analysis/func-mapping-test.cpp
tools/clang-extdef-mapping/ClangExtDefMapGen.cpp

index a712560790f62bef31be25203286802dfd90f326..bf9ee8d1a027154241a02894ff01149885f73ba3 100644 (file)
@@ -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);
index f43180a2a279ee878265d935bc63581fd45afb5c..bd8a022eb4d0ca4a8d335b863b8dda027fa5afd6 100644 (file)
@@ -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);
 }
index a9ff6b5a93a57d9203a75d64be8e0c9fdd81d162..c2410ced35dcfafb54e197c872a338c054f1e452 100644 (file)
@@ -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;
index 3df181b29d51eacf21f9ea5e2594545124b82a5f..da95098f4c83cfc3e89a1f195ad6daeb86ff2db3 100644 (file)
@@ -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
index 1cb0d4a9d774eb77c5687c2e85fe478c687f625b..aae4808e90ffece081ce59c608bfdf422b78d927 100644 (file)
@@ -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}}
 }
index f6eeb261da5164c23d2e343d0cde994eab811091..5c04d9411fee91e0d5b9ac6fd5f8da138b0687fd 100644 (file)
@@ -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;
+};
index 7a374698f7b3017a5113b4de8cc5c488816bdfe0..3c015fef93c168a8483b61eb9ddf1c523202bba0 100644 (file)
@@ -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;