[clang] 0b12efc - [clang][dataflow] Add support for nested method calls.
Yitzhak Mandelbaum via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 22 12:16:55 PDT 2022
Author: Yitzhak Mandelbaum
Date: 2022-09-22T19:16:31Z
New Revision: 0b12efc7a42c187400f7df18d5fd629d92d2747e
URL: https://github.com/llvm/llvm-project/commit/0b12efc7a42c187400f7df18d5fd629d92d2747e
DIFF: https://github.com/llvm/llvm-project/commit/0b12efc7a42c187400f7df18d5fd629d92d2747e.diff
LOG: [clang][dataflow] Add support for nested method calls.
Extend the context-sensitive analysis to handle a call to a method (of the same
class) from within a method. That, is a member-call expression through `this`.
Differential Revision: https://reviews.llvm.org/D134432
Added:
Modified:
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 8b761bef226ac..71ab89d56ed90 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -216,7 +216,10 @@ Environment Environment::pushCall(const CallExpr *Call) const {
if (const auto *MethodCall = dyn_cast<CXXMemberCallExpr>(Call)) {
if (const Expr *Arg = MethodCall->getImplicitObjectArgument()) {
- Env.ThisPointeeLoc = getStorageLocation(*Arg, SkipPast::Reference);
+ if (!isa<CXXThisExpr>(Arg))
+ Env.ThisPointeeLoc = getStorageLocation(*Arg, SkipPast::Reference);
+ // Otherwise (when the argument is `this`), retain the current
+ // environment's `ThisPointeeLoc`.
}
}
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index 4616265ad2598..3a827577bd78f 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -4359,7 +4359,7 @@ TEST(TransferTest, ContextSensitiveMethodSetter) {
std::string Code = R"(
class MyClass {
public:
- bool setField(bool Val) { Field = Val; }
+ void setField(bool Val) { Field = Val; }
bool Field;
};
@@ -4392,7 +4392,7 @@ TEST(TransferTest, ContextSensitiveMethodGetterAndSetter) {
class MyClass {
public:
bool getField() { return Field; }
- bool setField(bool Val) { Field = Val; }
+ void setField(bool Val) { Field = Val; }
private:
bool Field;
@@ -4421,6 +4421,73 @@ TEST(TransferTest, ContextSensitiveMethodGetterAndSetter) {
{TransferOptions{ContextSensitiveOptions{}}});
}
+
+TEST(TransferTest, ContextSensitiveMethodTwoLayersVoid) {
+ std::string Code = R"(
+ class MyClass {
+ public:
+ void Inner() { MyField = true; }
+ void Outer() { Inner(); }
+
+ bool MyField;
+ };
+
+ void target() {
+ MyClass MyObj;
+ MyObj.Outer();
+ bool Foo = MyObj.MyField;
+ // [[p]]
+ }
+ )";
+ 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());
+
+ auto &FooVal = *cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
+ EXPECT_TRUE(Env.flowConditionImplies(FooVal));
+ },
+ {TransferOptions{ContextSensitiveOptions{}}});
+}
+
+TEST(TransferTest, ContextSensitiveMethodTwoLayersReturn) {
+ std::string Code = R"(
+ class MyClass {
+ public:
+ bool Inner() { return MyField; }
+ bool Outer() { return Inner(); }
+
+ bool MyField;
+ };
+
+ void target() {
+ MyClass MyObj;
+ MyObj.MyField = true;
+ bool Foo = MyObj.Outer();
+ // [[p]]
+ }
+ )";
+ 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());
+
+ auto &FooVal = *cast<BoolValue>(Env.getValue(*FooDecl, SkipPast::None));
+ EXPECT_TRUE(Env.flowConditionImplies(FooVal));
+ },
+ {TransferOptions{ContextSensitiveOptions{}}});
+}
+
TEST(TransferTest, ContextSensitiveConstructorBody) {
std::string Code = R"(
class MyClass {
More information about the cfe-commits
mailing list