diff options
author | martinboehme <mboehme@google.com> | 2024-04-23 08:10:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-23 08:10:55 +0200 |
commit | 9ba6961ce05b17a70c22354f0b54a963ed1ab49c (patch) | |
tree | b8400f6ab5561851fb0da81bdeeffb062debfb49 /clang/unittests/Analysis/FlowSensitive/TransferTest.cpp | |
parent | 4513050f526be8bc17883685efec91a15ae427f8 (diff) | |
download | llvm-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.cpp | 68 |
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{}}}); } |