This revision was automatically updated to reflect the committed changes.
Closed by commit rG1a42f795587b: [clang][dataflow] Don't analyze templated
declarations. (authored by mboehme).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D150352/new/
https://reviews.llvm.org/D150352
Files:
clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp
clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/unittests/Analysis/FlowSensitive/TestingSupport.h
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
Index: clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
===================================================================
--- clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
@@ -68,7 +68,7 @@
assert(Body != nullptr);
auto CFCtx = llvm::cantFail(
- ControlFlowContext::build(nullptr, *Body, AST->getASTContext()));
+ ControlFlowContext::build(*Func, *Body, AST->getASTContext()));
AnalysisT Analysis = MakeAnalysis(AST->getASTContext());
DataflowAnalysisContext DACtx(std::make_unique<WatchedLiteralsSolver>());
Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===================================================================
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -39,12 +39,16 @@
using BuiltinOptions = DataflowAnalysisContext::Options;
template <typename Matcher>
-void runDataflow(llvm::StringRef Code, Matcher Match,
- DataflowAnalysisOptions Options,
- LangStandard::Kind Std = LangStandard::lang_cxx17,
- llvm::StringRef TargetFun = "target") {
+llvm::Error
+runDataflowReturnError(llvm::StringRef Code, Matcher Match,
+ DataflowAnalysisOptions Options,
+ LangStandard::Kind Std = LangStandard::lang_cxx17,
+ llvm::StringRef TargetFun = "target") {
using ast_matchers::hasName;
llvm::SmallVector<std::string, 3> ASTBuildArgs = {
+ // -fnodelayed-template-parsing is the default everywhere but on Windows.
+ // Set it explicitly so that tests behave the same on Windows as on other
+ // platforms.
"-fsyntax-only", "-fno-delayed-template-parsing",
"-std=" +
std::string(LangStandard::getLangStandardForKind(Std).getName())};
@@ -61,13 +65,21 @@
AI.ASTBuildArgs = ASTBuildArgs;
if (Options.BuiltinOpts)
AI.BuiltinOptions = *Options.BuiltinOpts;
+ return checkDataflow<NoopAnalysis>(
+ std::move(AI),
+ /*VerifyResults=*/
+ [&Match](
+ const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ const AnalysisOutputs &AO) { Match(Results, AO.ASTCtx); });
+}
+
+template <typename Matcher>
+void runDataflow(llvm::StringRef Code, Matcher Match,
+ DataflowAnalysisOptions Options,
+ LangStandard::Kind Std = LangStandard::lang_cxx17,
+ llvm::StringRef TargetFun = "target") {
ASSERT_THAT_ERROR(
- checkDataflow<NoopAnalysis>(
- std::move(AI),
- /*VerifyResults=*/
- [&Match](const llvm::StringMap<DataflowAnalysisState<NoopLattice>>
- &Results,
- const AnalysisOutputs &AO) { Match(Results, AO.ASTCtx); }),
+ runDataflowReturnError(Code, Match, Options, Std, TargetFun),
llvm::Succeeded());
}
@@ -2534,31 +2546,34 @@
});
}
-TEST(TransferTest, DerefDependentPtr) {
+TEST(TransferTest, CannotAnalyzeFunctionTemplate) {
std::string Code = R"(
template <typename T>
- void target(T *Foo) {
- T &Bar = *Foo;
- /*[[p]]*/
- }
+ void target() {}
)";
- runDataflow(
- Code,
- [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
- ASTContext &ASTCtx) {
- ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
- const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
-
- const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
- ASSERT_THAT(FooDecl, NotNull());
-
- const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
- ASSERT_THAT(BarDecl, NotNull());
+ ASSERT_THAT_ERROR(
+ runDataflowReturnError(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {},
+ {BuiltinOptions()}),
+ llvm::FailedWithMessage("Cannot analyze templated declarations"));
+}
- const auto *FooVal = cast<PointerValue>(Env.getValue(*FooDecl));
- const auto *BarLoc = Env.getStorageLocation(*BarDecl);
- EXPECT_EQ(BarLoc, &FooVal->getPointeeLoc());
- });
+TEST(TransferTest, CannotAnalyzeMethodOfClassTemplate) {
+ std::string Code = R"(
+ template <typename T>
+ struct A {
+ void target() {}
+ };
+ )";
+ ASSERT_THAT_ERROR(
+ runDataflowReturnError(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {},
+ {BuiltinOptions()}),
+ llvm::FailedWithMessage("Cannot analyze templated declarations"));
}
TEST(TransferTest, VarDeclInitAssignConditionalOperator) {
Index: clang/unittests/Analysis/FlowSensitive/TestingSupport.h
===================================================================
--- clang/unittests/Analysis/FlowSensitive/TestingSupport.h
+++ clang/unittests/Analysis/FlowSensitive/TestingSupport.h
@@ -242,7 +242,7 @@
// Build the control flow graph for the target function.
auto MaybeCFCtx =
- ControlFlowContext::build(Target, *Target->getBody(), Context);
+ ControlFlowContext::build(*Target, *Target->getBody(), Context);
if (!MaybeCFCtx) return MaybeCFCtx.takeError();
auto &CFCtx = *MaybeCFCtx;
Index: clang/lib/Analysis/FlowSensitive/Transfer.cpp
===================================================================
--- clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -424,9 +424,8 @@
switch (S->getOpcode()) {
case UO_Deref: {
- // Skip past a reference to handle dereference of a dependent pointer.
- const auto *SubExprVal = cast_or_null<PointerValue>(
- Env.getValue(*SubExpr, SkipPast::Reference));
+ const auto *SubExprVal =
+ cast_or_null<PointerValue>(Env.getValue(*SubExpr, SkipPast::None));
if (SubExprVal == nullptr)
break;
Index: clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
===================================================================
--- clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -211,7 +211,7 @@
return &It->second;
if (Stmt *Body = F->getBody()) {
- auto CFCtx = ControlFlowContext::build(F, *Body, F->getASTContext());
+ auto CFCtx = ControlFlowContext::build(*F, *Body, F->getASTContext());
// FIXME: Handle errors.
assert(CFCtx);
auto Result = FunctionContexts.insert({F, std::move(*CFCtx)});
Index: clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp
===================================================================
--- clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp
+++ clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp
@@ -68,7 +68,12 @@
}
llvm::Expected<ControlFlowContext>
-ControlFlowContext::build(const Decl *D, Stmt &S, ASTContext &C) {
+ControlFlowContext::build(const Decl &D, Stmt &S, ASTContext &C) {
+ if (D.isTemplated())
+ return llvm::createStringError(
+ std::make_error_code(std::errc::invalid_argument),
+ "Cannot analyze templated declarations");
+
CFG::BuildOptions Options;
Options.PruneTriviallyFalseEdges = true;
Options.AddImplicitDtors = true;
@@ -79,7 +84,7 @@
// Ensure that all sub-expressions in basic blocks are evaluated.
Options.setAllAlwaysAdd();
- auto Cfg = CFG::buildCFG(D, &S, &C, Options);
+ auto Cfg = CFG::buildCFG(&D, &S, &C, Options);
if (Cfg == nullptr)
return llvm::createStringError(
std::make_error_code(std::errc::invalid_argument),
@@ -90,9 +95,19 @@
llvm::BitVector BlockReachable = findReachableBlocks(*Cfg);
- return ControlFlowContext(D, std::move(Cfg), std::move(StmtToBlock),
+ return ControlFlowContext(&D, std::move(Cfg), std::move(StmtToBlock),
std::move(BlockReachable));
}
+llvm::Expected<ControlFlowContext>
+ControlFlowContext::build(const Decl *D, Stmt &S, ASTContext &C) {
+ if (D == nullptr)
+ return llvm::createStringError(
+ std::make_error_code(std::errc::invalid_argument),
+ "Declaration must not be null");
+
+ return build(*D, S, C);
+}
+
} // namespace dataflow
} // namespace clang
Index: clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
===================================================================
--- clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
+++ clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
@@ -32,7 +32,13 @@
class ControlFlowContext {
public:
/// Builds a ControlFlowContext from an AST node. `D` is the function in which
- /// `S` resides and must not be null.
+ /// `S` resides. `D.isTemplated()` must be false.
+ static llvm::Expected<ControlFlowContext> build(const Decl &D, Stmt &S,
+ ASTContext &C);
+
+ /// Builds a ControlFlowContext from an AST node. `D` is the function in which
+ /// `S` resides. `D` must not be null and `D->isTemplated()` must be false.
+ LLVM_DEPRECATED("Use the version that takes a const Decl & instead", "")
static llvm::Expected<ControlFlowContext> build(const Decl *D, Stmt &S,
ASTContext &C);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits