aboutsummaryrefslogtreecommitdiff
path: root/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
diff options
context:
space:
mode:
authormartinboehme <mboehme@google.com>2024-04-23 08:10:55 +0200
committerGitHub <noreply@github.com>2024-04-23 08:10:55 +0200
commit9ba6961ce05b17a70c22354f0b54a963ed1ab49c (patch)
treeb8400f6ab5561851fb0da81bdeeffb062debfb49 /clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
parent4513050f526be8bc17883685efec91a15ae427f8 (diff)
downloadllvm-9ba6961ce05b17a70c22354f0b54a963ed1ab49c.zip
llvm-9ba6961ce05b17a70c22354f0b54a963ed1ab49c.tar.gz
llvm-9ba6961ce05b17a70c22354f0b54a963ed1ab49c.tar.bz2
Reapply "[clang][dataflow] Model conditional operator correctly." with fixes (#89596)
I reverted https://github.com/llvm/llvm-project/pull/89213 beause it was causing buildbots to fail with assertion failures. Embarrassingly, it turns out I had been running tests locally in `Release` mode, i.e. with `assert()` compiled away. This PR re-lands #89213 with fixes for the failing assertions.
Diffstat (limited to 'clang/unittests/Analysis/FlowSensitive/TransferTest.cpp')
-rw-r--r--clang/unittests/Analysis/FlowSensitive/TransferTest.cpp68
1 files changed, 63 insertions, 5 deletions
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index bb16138..215e208 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3637,7 +3637,7 @@ TEST(TransferTest, VarDeclInitAssignConditionalOperator) {
};
void target(A Foo, A Bar, bool Cond) {
- A Baz = Cond ? Foo : Bar;
+ A Baz = Cond ? A(Foo) : A(Bar);
// Make sure A::i is modeled.
Baz.i;
/*[[p]]*/
@@ -5275,6 +5275,67 @@ TEST(TransferTest, BinaryOperatorComma) {
});
}
+TEST(TransferTest, ConditionalOperatorValue) {
+ std::string Code = R"(
+ void target(bool Cond, bool B1, bool B2) {
+ bool JoinSame = Cond ? B1 : B1;
+ bool JoinDifferent = Cond ? B1 : B2;
+ // [[p]]
+ }
+ )";
+ runDataflow(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {
+ Environment Env = getEnvironmentAtAnnotation(Results, "p").fork();
+
+ auto &B1 = getValueForDecl<BoolValue>(ASTCtx, Env, "B1");
+ auto &B2 = getValueForDecl<BoolValue>(ASTCtx, Env, "B2");
+ auto &JoinSame = getValueForDecl<BoolValue>(ASTCtx, Env, "JoinSame");
+ auto &JoinDifferent =
+ getValueForDecl<BoolValue>(ASTCtx, Env, "JoinDifferent");
+
+ EXPECT_EQ(&JoinSame, &B1);
+
+ const Formula &JoinDifferentEqB1 =
+ Env.arena().makeEquals(JoinDifferent.formula(), B1.formula());
+ EXPECT_TRUE(Env.allows(JoinDifferentEqB1));
+ EXPECT_FALSE(Env.proves(JoinDifferentEqB1));
+
+ const Formula &JoinDifferentEqB2 =
+ Env.arena().makeEquals(JoinDifferent.formula(), B2.formula());
+ EXPECT_TRUE(Env.allows(JoinDifferentEqB2));
+ EXPECT_FALSE(Env.proves(JoinDifferentEqB1));
+ });
+}
+
+TEST(TransferTest, ConditionalOperatorLocation) {
+ std::string Code = R"(
+ void target(bool Cond, int I1, int I2) {
+ int &JoinSame = Cond ? I1 : I1;
+ int &JoinDifferent = Cond ? I1 : I2;
+ // [[p]]
+ }
+ )";
+ runDataflow(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {
+ Environment Env = getEnvironmentAtAnnotation(Results, "p").fork();
+
+ StorageLocation &I1 = getLocForDecl(ASTCtx, Env, "I1");
+ StorageLocation &I2 = getLocForDecl(ASTCtx, Env, "I2");
+ StorageLocation &JoinSame = getLocForDecl(ASTCtx, Env, "JoinSame");
+ StorageLocation &JoinDifferent =
+ getLocForDecl(ASTCtx, Env, "JoinDifferent");
+
+ EXPECT_EQ(&JoinSame, &I1);
+
+ EXPECT_NE(&JoinDifferent, &I1);
+ EXPECT_NE(&JoinDifferent, &I2);
+ });
+}
+
TEST(TransferTest, IfStmtBranchExtendsFlowCondition) {
std::string Code = R"(
void target(bool Foo) {
@@ -5522,10 +5583,7 @@ TEST(TransferTest, ContextSensitiveReturnReferenceWithConditionalOperator) {
auto *Loc = Env.getReturnStorageLocation();
EXPECT_THAT(Loc, NotNull());
- // TODO: We would really like to make this stronger assertion, but that
- // doesn't work because we don't propagate values correctly through
- // the conditional operator yet.
- // EXPECT_EQ(Loc, SLoc);
+ EXPECT_EQ(Loc, SLoc);
},
{BuiltinOptions{ContextSensitiveOptions{}}});
}