samestep created this revision.
Herald added subscribers: martong, xazax.hun.
Herald added a reviewer: NoQ.
Herald added a project: All.
samestep requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D131779
Files:
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
clang/include/clang/Analysis/FlowSensitive/Transfer.h
clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===================================================================
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -64,7 +64,10 @@
LangStandard::Kind Std = LangStandard::lang_cxx17,
bool ApplyBuiltinTransfer = true,
llvm::StringRef TargetFun = "target") {
- runDataflow(Code, Match, {ApplyBuiltinTransfer, {}}, Std, TargetFun);
+ runDataflow(Code, Match,
+ {ApplyBuiltinTransfer ? TransferOptions{}
+ : llvm::Optional<TransferOptions>()},
+ Std, TargetFun);
}
TEST(TransferTest, IntVarDeclNotTrackedWhenTransferDisabled) {
@@ -3896,8 +3899,7 @@
EXPECT_FALSE(Env.flowConditionImplies(FooVal));
EXPECT_FALSE(Env.flowConditionImplies(Env.makeNot(FooVal)));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/false}});
+ {TransferOptions{llvm::Optional<ContextSensitiveOptions>()}});
}
TEST(TransferTest, ContextSensitiveSetTrue) {
@@ -3926,8 +3928,7 @@
*cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
EXPECT_TRUE(Env.flowConditionImplies(FooVal));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveSetFalse) {
@@ -3956,8 +3957,7 @@
*cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
EXPECT_TRUE(Env.flowConditionImplies(Env.makeNot(FooVal)));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveSetBothTrueAndFalse) {
@@ -3997,8 +3997,7 @@
EXPECT_FALSE(Env.flowConditionImplies(BarVal));
EXPECT_TRUE(Env.flowConditionImplies(Env.makeNot(BarVal)));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveSetTwoLayers) {
@@ -4029,8 +4028,7 @@
EXPECT_FALSE(Env.flowConditionImplies(FooVal));
EXPECT_FALSE(Env.flowConditionImplies(Env.makeNot(FooVal)));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveSetMultipleLines) {
@@ -4071,8 +4069,7 @@
EXPECT_FALSE(Env.flowConditionImplies(BarVal));
EXPECT_TRUE(Env.flowConditionImplies(Env.makeNot(BarVal)));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveSetMultipleBlocks) {
@@ -4117,8 +4114,7 @@
EXPECT_TRUE(Env.flowConditionImplies(BazVal));
EXPECT_FALSE(Env.flowConditionImplies(Env.makeNot(BazVal)));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveReturnVoid) {
@@ -4138,8 +4134,7 @@
ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
// This just tests that the analysis doesn't crash.
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveReturnTrue) {
@@ -4166,8 +4161,7 @@
*cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
EXPECT_TRUE(Env.flowConditionImplies(FooVal));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveReturnFalse) {
@@ -4194,8 +4188,7 @@
*cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
EXPECT_TRUE(Env.flowConditionImplies(Env.makeNot(FooVal)));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveReturnArg) {
@@ -4225,8 +4218,7 @@
*cast<BoolValue>(Env.getValue(*BazDecl, SkipPast::None));
EXPECT_TRUE(Env.flowConditionImplies(BazVal));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveReturnInt) {
@@ -4246,8 +4238,7 @@
ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
// This just tests that the analysis doesn't crash.
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveMethodLiteral) {
@@ -4278,8 +4269,7 @@
*cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
EXPECT_TRUE(Env.flowConditionImplies(FooVal));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveMethodGetter) {
@@ -4313,8 +4303,7 @@
*cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
EXPECT_TRUE(Env.flowConditionImplies(FooVal));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveMethodSetter) {
@@ -4348,8 +4337,7 @@
*cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
EXPECT_TRUE(Env.flowConditionImplies(FooVal));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveMethodGetterAndSetter) {
@@ -4385,8 +4373,7 @@
*cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
EXPECT_TRUE(Env.flowConditionImplies(FooVal));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveConstructorBody) {
@@ -4419,8 +4406,7 @@
*cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
EXPECT_TRUE(Env.flowConditionImplies(FooVal));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveConstructorInitializer) {
@@ -4453,8 +4439,7 @@
*cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
EXPECT_TRUE(Env.flowConditionImplies(FooVal));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
TEST(TransferTest, ContextSensitiveConstructorDefault) {
@@ -4487,8 +4472,7 @@
*cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
EXPECT_TRUE(Env.flowConditionImplies(FooVal));
},
- {/*.ApplyBuiltinTransfer=*/true,
- /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+ {TransferOptions{ContextSensitiveOptions{}}});
}
} // namespace
Index: clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
===================================================================
--- clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -200,7 +200,7 @@
}
llvm::Optional<TypeErasedDataflowAnalysisState> MaybeState;
- bool ApplyBuiltinTransfer = Analysis.applyBuiltinTransfer();
+ auto BuiltinTransferOpts = Analysis.builtinTransferOptions();
for (const CFGBlock *Pred : Preds) {
// Skip if the `Block` is unreachable or control flow cannot get past it.
@@ -215,12 +215,12 @@
continue;
TypeErasedDataflowAnalysisState PredState = MaybePredState.value();
- if (ApplyBuiltinTransfer) {
+ if (BuiltinTransferOpts) {
if (const Stmt *PredTerminatorStmt = Pred->getTerminatorStmt()) {
const StmtToEnvMapImpl StmtToEnv(CFCtx, BlockStates);
TerminatorVisitor(StmtToEnv, PredState.Env,
blockIndexInPredecessor(*Pred, Block),
- Analysis.builtinTransferOptions())
+ *BuiltinTransferOpts)
.Visit(PredTerminatorStmt);
}
}
@@ -255,9 +255,10 @@
const Stmt *S = CfgStmt.getStmt();
assert(S != nullptr);
- if (Analysis.applyBuiltinTransfer())
+ auto BuiltinTransferOpts = Analysis.builtinTransferOptions();
+ if (BuiltinTransferOpts)
transfer(StmtToEnvMapImpl(CFCtx, BlockStates), *S, State.Env,
- Analysis.builtinTransferOptions());
+ *BuiltinTransferOpts);
Analysis.transferTypeErased(S, State.Lattice, State.Env);
if (HandleTransferredStmt != nullptr)
@@ -318,7 +319,7 @@
State, HandleTransferredStmt);
break;
case CFGElement::Initializer:
- if (Analysis.applyBuiltinTransfer())
+ if (Analysis.builtinTransferOptions().hasValue())
transferCFGInitializer(*Element.getAs<CFGInitializer>(), State);
break;
default:
Index: clang/lib/Analysis/FlowSensitive/Transfer.cpp
===================================================================
--- clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -661,7 +661,7 @@
// `F` of `S`. The type `E` must be either `CallExpr` or `CXXConstructExpr`.
template <typename E>
void transferInlineCall(const E *S, const FunctionDecl *F) {
- if (!Options.ContextSensitive)
+ if (!Options.ContextSensitiveOpts)
return;
const ControlFlowContext *CFCtx = Env.getControlFlowContext(F);
Index: clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
===================================================================
--- clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
+++ clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
@@ -32,14 +32,11 @@
namespace dataflow {
struct DataflowAnalysisOptions {
- /// Determines whether to apply the built-in transfer functions.
+ /// Options for the built-in transfer functions, or empty to not apply them.
// FIXME: Remove this option once the framework supports composing analyses
// (at which point the built-in transfer functions can be simply a standalone
// analysis).
- bool ApplyBuiltinTransfer = true;
-
- /// Only has an effect if `ApplyBuiltinTransfer` is true.
- TransferOptions BuiltinTransferOptions;
+ llvm::Optional<TransferOptions> BuiltinTransferOpts = TransferOptions{};
};
/// Type-erased lattice element container.
@@ -87,13 +84,11 @@
virtual void transferTypeErased(const Stmt *, TypeErasedLattice &,
Environment &) = 0;
- /// Determines whether to apply the built-in transfer functions, which model
- /// the heap and stack in the `Environment`.
- bool applyBuiltinTransfer() const { return Options.ApplyBuiltinTransfer; }
-
- /// Returns the options to be passed to the built-in transfer functions.
- TransferOptions builtinTransferOptions() const {
- return Options.BuiltinTransferOptions;
+ /// If the built-in transfer functions (which model the heap and stack in the
+ /// `Environment`) are to be applied, returns the options to be passed to
+ /// them. Otherwise returns empty.
+ llvm::Optional<TransferOptions> builtinTransferOptions() const {
+ return Options.BuiltinTransferOpts;
}
};
Index: clang/include/clang/Analysis/FlowSensitive/Transfer.h
===================================================================
--- clang/include/clang/Analysis/FlowSensitive/Transfer.h
+++ clang/include/clang/Analysis/FlowSensitive/Transfer.h
@@ -16,17 +16,19 @@
#include "clang/AST/Stmt.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "llvm/ADT/Optional.h"
namespace clang {
namespace dataflow {
+struct ContextSensitiveOptions {};
+
struct TransferOptions {
- /// Determines whether to analyze function bodies when present in the
- /// translation unit. Note: this is currently only meant to be used for
- /// inlining of specialized model code, not for context-sensitive analysis of
- /// arbitrary subject code. In particular, some fundamentals such as recursion
- /// are explicitly unsupported.
- bool ContextSensitive = false;
+ /// Options for analyzing function bodies when present in the translation
+ /// unit, or empty to disable context-sensitive analysis. Note that this is
+ /// fundamentally limited: some constructs, such as recursion, are explicitly
+ /// unsupported.
+ llvm::Optional<ContextSensitiveOptions> ContextSensitiveOpts;
};
/// Maps statements to the environments of basic blocks that contain them.
Index: clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
===================================================================
--- clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
+++ clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
@@ -65,8 +65,9 @@
/// Deprecated. Use the `DataflowAnalysisOptions` constructor instead.
explicit DataflowAnalysis(ASTContext &Context, bool ApplyBuiltinTransfer)
- : DataflowAnalysis(Context, DataflowAnalysisOptions{ApplyBuiltinTransfer,
- TransferOptions{}}) {}
+ : DataflowAnalysis(Context, {ApplyBuiltinTransfer
+ ? TransferOptions{}
+ : llvm::Optional<TransferOptions>()}) {}
explicit DataflowAnalysis(ASTContext &Context,
DataflowAnalysisOptions Options)
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits