[clang] e63b81d - [analyzer][ctu] Only import const and trivial VarDecls
Gabor Marton via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 1 04:54:17 PDT 2022
Author: Gabor Marton
Date: 2022-04-01T13:49:39+02:00
New Revision: e63b81d10e023b4d8e9f61ca29a678c74ce2c1cb
URL: https://github.com/llvm/llvm-project/commit/e63b81d10e023b4d8e9f61ca29a678c74ce2c1cb
DIFF: https://github.com/llvm/llvm-project/commit/e63b81d10e023b4d8e9f61ca29a678c74ce2c1cb.diff
LOG: [analyzer][ctu] Only import const and trivial VarDecls
Do import the definition of objects from a foreign translation unit if that's type is const and trivial.
Differential Revision: https://reviews.llvm.org/D122805
Added:
Modified:
clang/include/clang/CrossTU/CrossTranslationUnit.h
clang/lib/CrossTU/CrossTranslationUnit.cpp
clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
clang/test/Analysis/Inputs/ctu-other.cpp
clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
clang/test/Analysis/ctu-main.cpp
clang/test/Analysis/func-mapping-test.cpp
clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/CrossTU/CrossTranslationUnit.h b/clang/include/clang/CrossTU/CrossTranslationUnit.h
index a09826f93afc0..a41c32d4068b2 100644
--- a/clang/include/clang/CrossTU/CrossTranslationUnit.h
+++ b/clang/include/clang/CrossTU/CrossTranslationUnit.h
@@ -109,8 +109,10 @@ llvm::Expected<InvocationListTy> parseInvocationList(
StringRef FileContent,
llvm::sys::path::Style PathStyle = llvm::sys::path::Style::posix);
-// Returns true if the variable or any field of a record variable is const.
-bool containsConst(const VarDecl *VD, const ASTContext &ACtx);
+/// Returns true if it makes sense to import a foreign variable definition.
+/// For instance, we don't want to import variables that have non-trivial types
+/// because the constructor might have side-effects.
+bool shouldImport(const VarDecl *VD, const ASTContext &ACtx);
/// This class is used for tools that requires cross translation
/// unit capability.
diff --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp b/clang/lib/CrossTU/CrossTranslationUnit.cpp
index cbe07acb76fb1..ee6cc60f31e1d 100644
--- a/clang/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp
@@ -220,14 +220,9 @@ createCrossTUIndexString(const llvm::StringMap<std::string> &Index) {
return Result.str();
}
-bool containsConst(const VarDecl *VD, const ASTContext &ACtx) {
+bool shouldImport(const VarDecl *VD, const ASTContext &ACtx) {
CanQualType CT = ACtx.getCanonicalType(VD->getType());
- if (!CT.isConstQualified()) {
- const RecordType *RTy = CT->getAs<RecordType>();
- if (!RTy || !RTy->hasConstFields())
- return false;
- }
- return true;
+ return CT.isConstQualified() && VD->getType().isTrivialType(ACtx);
}
static bool hasBodyOrInit(const FunctionDecl *D, const FunctionDecl *&DefD) {
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 9e96e00011f4f..fcc73b3767d4b 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -289,7 +289,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
return true;
if (VD->hasExternalStorage() || VD->isStaticDataMember()) {
- if (!cross_tu::containsConst(VD, *Ctx))
+ if (!cross_tu::shouldImport(VD, *Ctx))
return true;
} else {
// Cannot be initialized in another TU.
diff --git a/clang/test/Analysis/Inputs/ctu-other.cpp b/clang/test/Analysis/Inputs/ctu-other.cpp
index ff37947d5b7e9..a7bf1cef65b92 100644
--- a/clang/test/Analysis/Inputs/ctu-other.cpp
+++ b/clang/test/Analysis/Inputs/ctu-other.cpp
@@ -102,6 +102,12 @@ struct S {
int a;
};
extern const S extS = {.a = 4};
+extern S extNonConstS = {.a = 4};
+struct NonTrivialS {
+ int a;
+ ~NonTrivialS();
+};
+extern const NonTrivialS extNTS = {.a = 4};
struct A {
static const int a;
};
@@ -109,18 +115,18 @@ const int A::a = 3;
struct SC {
const int a;
};
-SC extSC = {.a = 8};
+extern const SC extSC = {.a = 8};
struct ST {
- static struct SC sc;
+ static const struct SC sc;
};
-struct SC ST::sc = {.a = 2};
+const struct SC ST::sc = {.a = 2};
struct SCNest {
struct SCN {
const int a;
} scn;
};
SCNest extSCN = {.scn = {.a = 9}};
-SCNest::SCN extSubSCN = {.a = 1};
+extern SCNest::SCN const extSubSCN = {.a = 1};
struct SCC {
SCC(int c) : a(c) {}
const int a;
@@ -130,7 +136,7 @@ union U {
const int a;
const unsigned int b;
};
-U extU = {.a = 4};
+extern const U extU = {.a = 4};
class TestAnonUnionUSR {
public:
diff --git a/clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt b/clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
index 476b8f1867042..439232333b609 100644
--- a/clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
+++ b/clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
@@ -18,6 +18,7 @@
9:c:@extInt ctu-other.cpp.ast
17:c:@N at intns@extInt ctu-other.cpp.ast
7:c:@extS ctu-other.cpp.ast
+9:c:@extNTS ctu-other.cpp.ast
8:c:@S at A@a ctu-other.cpp.ast
8:c:@extSC ctu-other.cpp.ast
10:c:@S at ST@sc ctu-other.cpp.ast
diff --git a/clang/test/Analysis/ctu-main.cpp b/clang/test/Analysis/ctu-main.cpp
index d76b3984401e0..5bf212a123e9f 100644
--- a/clang/test/Analysis/ctu-main.cpp
+++ b/clang/test/Analysis/ctu-main.cpp
@@ -74,6 +74,13 @@ struct S {
int a;
};
extern const S extS;
+extern S extNonConstS;
+struct NonTrivialS {
+ int a;
+ // User declaring a dtor makes it non-trivial.
+ ~NonTrivialS();
+};
+extern const NonTrivialS extNTS;
extern const int extHere;
const int extHere = 6;
struct A {
@@ -82,9 +89,9 @@ struct A {
struct SC {
const int a;
};
-extern SC extSC;
+extern const SC extSC;
struct ST {
- static struct SC sc;
+ static const struct SC sc;
};
struct SCNest {
struct SCN {
@@ -92,7 +99,7 @@ struct SCNest {
} scn;
};
extern SCNest extSCN;
-extern SCNest::SCN extSubSCN;
+extern const SCNest::SCN extSubSCN;
struct SCC {
SCC(int c);
const int a;
@@ -102,7 +109,7 @@ union U {
const int a;
const unsigned int b;
};
-extern U extU;
+extern const U extU;
void test_virtual_functions(mycls* obj) {
// The dynamic type is known.
@@ -153,6 +160,9 @@ int main() {
clang_analyzer_eval(extInt == 2); // expected-warning{{TRUE}}
clang_analyzer_eval(intns::extInt == 3); // expected-warning{{TRUE}}
clang_analyzer_eval(extS.a == 4); // expected-warning{{TRUE}}
+ clang_analyzer_eval(extNonConstS.a == 4); // expected-warning{{TRUE}} expected-warning{{FALSE}}
+ // Do not import non-trivial classes' initializers.
+ clang_analyzer_eval(extNTS.a == 4); // expected-warning{{TRUE}} expected-warning{{FALSE}}
clang_analyzer_eval(extHere == 6); // expected-warning{{TRUE}}
clang_analyzer_eval(A::a == 3); // expected-warning{{TRUE}}
clang_analyzer_eval(extSC.a == 8); // expected-warning{{TRUE}}
diff --git a/clang/test/Analysis/func-mapping-test.cpp b/clang/test/Analysis/func-mapping-test.cpp
index 44bbf85097201..a56c0075db1aa 100644
--- a/clang/test/Analysis/func-mapping-test.cpp
+++ b/clang/test/Analysis/func-mapping-test.cpp
@@ -23,7 +23,7 @@ extern S const s = {.a = 2};
struct SF {
const int a;
};
-SF sf = {.a = 2};
+extern const SF sf = {.a = 2};
// CHECK-DAG: 5:c:@sf
struct SStatic {
@@ -39,7 +39,7 @@ union U {
const int a;
const unsigned int b;
};
-U u = {.a = 6};
+extern const U u = {.a = 6};
// CHECK-DAG: 4:c:@u
// No USR can be generated for this.
diff --git a/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp b/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
index 8aba1301ef9aa..bc8d2581c1b97 100644
--- a/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
+++ b/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
@@ -64,7 +64,7 @@ void MapExtDefNamesConsumer::handleDecl(const Decl *D) {
if (const Stmt *Body = FD->getBody())
addIfInMain(FD, Body->getBeginLoc());
} else if (const auto *VD = dyn_cast<VarDecl>(D)) {
- if (cross_tu::containsConst(VD, Ctx) && VD->hasInit())
+ if (cross_tu::shouldImport(VD, Ctx) && VD->hasInit())
if (const Expr *Init = VD->getInit())
addIfInMain(VD, Init->getBeginLoc());
}
More information about the cfe-commits
mailing list