diff options
author | martinboehme <mboehme@google.com> | 2024-04-25 09:24:08 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-25 09:24:08 +0200 |
commit | b9208ce318907b1a5ea4ad0d2aa4414dfba0616c (patch) | |
tree | 7cd4f221c17c2cce53114dbf694c421668edbc1d /clang/unittests/Analysis/FlowSensitive/TransferTest.cpp | |
parent | 9b0651f5ae6510577302ea527b2cc79e80ec9ccc (diff) | |
download | llvm-b9208ce318907b1a5ea4ad0d2aa4414dfba0616c.zip llvm-b9208ce318907b1a5ea4ad0d2aa4414dfba0616c.tar.gz llvm-b9208ce318907b1a5ea4ad0d2aa4414dfba0616c.tar.bz2 |
[clang][dataflow] Crash fix for `widenDistinctValues()`. (#89895)
We used to crash if the previous iteration contained a `BoolValue` and
the
current iteration contained an `IntegerValue`. The accompanying test
sets up
this situation -- see comments there for details.
While I'm here, clean up the tests for integral casts to use the test
helpers we
have available now. I was looking at these tests to understand how we
handle
integral casts, and the test helpers make the tests easier to read.
Diffstat (limited to 'clang/unittests/Analysis/FlowSensitive/TransferTest.cpp')
-rw-r--r-- | clang/unittests/Analysis/FlowSensitive/TransferTest.cpp | 65 |
1 files changed, 32 insertions, 33 deletions
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 5c7c39e..d2047009 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -3370,20 +3370,11 @@ TEST(TransferTest, IntegralCast) { 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()); - - const auto *FooVal = Env.getValue(*FooDecl); - const auto *BarVal = Env.getValue(*BarDecl); - EXPECT_TRUE(isa<IntegerValue>(FooVal)); - EXPECT_TRUE(isa<IntegerValue>(BarVal)); - EXPECT_EQ(FooVal, BarVal); + const auto &FooVal = getValueForDecl<IntegerValue>(ASTCtx, Env, "Foo"); + const auto &BarVal = getValueForDecl<IntegerValue>(ASTCtx, Env, "Bar"); + EXPECT_EQ(&FooVal, &BarVal); }); } @@ -3398,17 +3389,10 @@ TEST(TransferTest, IntegraltoBooleanCast) { 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()); - - const auto *FooVal = Env.getValue(*FooDecl); - const auto *BarVal = Env.getValue(*BarDecl); + const auto &FooVal = getValueForDecl(ASTCtx, Env, "Foo"); + const auto &BarVal = getValueForDecl(ASTCtx, Env, "Bar"); EXPECT_TRUE(isa<IntegerValue>(FooVal)); EXPECT_TRUE(isa<BoolValue>(BarVal)); }); @@ -3426,23 +3410,38 @@ TEST(TransferTest, IntegralToBooleanCastFromBool) { 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()); - - const auto *FooVal = Env.getValue(*FooDecl); - const auto *BarVal = Env.getValue(*BarDecl); - EXPECT_TRUE(isa<BoolValue>(FooVal)); - EXPECT_TRUE(isa<BoolValue>(BarVal)); - EXPECT_EQ(FooVal, BarVal); + const auto &FooVal = getValueForDecl<BoolValue>(ASTCtx, Env, "Foo"); + const auto &BarVal = getValueForDecl<BoolValue>(ASTCtx, Env, "Bar"); + EXPECT_EQ(&FooVal, &BarVal); }); } +TEST(TransferTest, WidenBoolValueInIntegerVariable) { + // This is a crash repro. + // This test sets up a case where we perform widening on an integer variable + // that contains a `BoolValue` for the previous iteration and an + // `IntegerValue` for the current iteration. We used to crash on this because + // `widenDistinctValues()` assumed that if the previous iteration had a + // `BoolValue`, the current iteration would too. + // FIXME: The real fix here is to make sure we never store `BoolValue`s in + // integer variables; see also the comment in `widenDistinctValues()`. + std::string Code = R"cc( + struct S { + int i; + S *next; + }; + void target(S *s) { + for (; s; s = s->next) + s->i = false; + } + )cc"; + runDataflow(Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &, + ASTContext &) {}); +} + TEST(TransferTest, NullToPointerCast) { std::string Code = R"( using my_nullptr_t = decltype(nullptr); |