https://github.com/haoNoQ created https://github.com/llvm/llvm-project/pull/178943
Just because the right-hand side of the assignment doesn't have a known value, doesn't mean the left-hand side gets to keep its old value. >From b07a3bf6a86d453813a3f139140375b65f7e74a6 Mon Sep 17 00:00:00 2001 From: Artem Dergachev <[email protected]> Date: Fri, 30 Jan 2026 13:41:07 -0500 Subject: [PATCH] [clang][dataflow] Fix assignment of unknown values. Just because the right-hand side of the assignment doesn't have a known value, doesn't mean the left-hand side gets to keep its old value. --- clang/lib/Analysis/FlowSensitive/Transfer.cpp | 2 +- .../Analysis/FlowSensitive/TransferTest.cpp | 76 +++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index 9d1b00293f394..51cc1f9bc26ab 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -170,7 +170,7 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> { auto *RHSVal = Env.getValue(*RHS); if (RHSVal == nullptr) - break; + RHSVal = Env.createValue(LHS->getType()); // Assign a value to the storage location of the left-hand side. Env.setValue(*LHSLoc, *RHSVal); diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index a6308d115aa70..5ff0983543369 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -935,6 +935,82 @@ TEST(TransferTest, BinaryOperatorAssignIntegerLiteral) { }); } +TEST(TransferTest, BinaryOperatorAssignUnknown) { + std::string Code = R"( + int unknown(); + + void target() { + int Foo = unknown(); + int FooAtA = Foo; + + Foo = unknown(); + int FooAtB = Foo; + + Foo += unknown(); + int FooAtC = Foo; + + // [[p]] + + if (FooAtA != FooAtB) { + (void)0; + // [[q]] + } + + if (FooAtB != FooAtC) { + (void)0; + // [[r]] + } + } + )"; + using ast_matchers::binaryOperator; + using ast_matchers::match; + using ast_matchers::selectFirst; + runDataflow( + Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, + ASTContext &ASTCtx) { + ASSERT_THAT(Results.keys(), UnorderedElementsAre("p", "q", "r")); + + // Check that the second unknown value is different. + const Environment &EnvP = getEnvironmentAtAnnotation(Results, "p"); + + const ValueDecl *FooAtADecl = findValueDecl(ASTCtx, "FooAtA"); + ASSERT_THAT(FooAtADecl, NotNull()); + const Value *FooAtAVal = EnvP.getValue(*FooAtADecl); + ASSERT_TRUE(isa_and_nonnull<IntegerValue>(FooAtAVal)); + + const ValueDecl *FooAtBDecl = findValueDecl(ASTCtx, "FooAtB"); + ASSERT_THAT(FooAtBDecl, NotNull()); + const Value *FooAtBVal = EnvP.getValue(*FooAtBDecl); + ASSERT_TRUE(isa_and_nonnull<IntegerValue>(FooAtBVal)); + + const ValueDecl *FooAtCDecl = findValueDecl(ASTCtx, "FooAtC"); + ASSERT_THAT(FooAtCDecl, NotNull()); + const Value *FooAtCVal = EnvP.getValue(*FooAtCDecl); + ASSERT_TRUE(isa_and_nonnull<IntegerValue>(FooAtCVal)); + + EXPECT_NE(FooAtAVal, FooAtBVal); + // FIXME: Should be NE too. + EXPECT_EQ(FooAtBVal, FooAtCVal); + + // Check that the storage location is correctly propagated. + auto MatchResult = match(binaryOperator().bind("bo"), ASTCtx); + const auto *BO = selectFirst<BinaryOperator>("bo", MatchResult); + EXPECT_NE(BO, nullptr); + const StorageLocation *BOLoc = EnvP.getStorageLocation(*BO); + EXPECT_NE(BOLoc, nullptr); + + // Check that the branches are reachable + // with a non-false flow condition. + const Environment &EnvQ = getEnvironmentAtAnnotation(Results, "q"); + const Environment &EnvR = getEnvironmentAtAnnotation(Results, "r"); + + EXPECT_FALSE(EnvQ.proves(EnvQ.arena().makeLiteral(false))); + // FIXME: Should be FALSE too. + EXPECT_TRUE(EnvR.proves(EnvR.arena().makeLiteral(false))); + }); +} + TEST(TransferTest, VarDeclInitAssign) { std::string Code = R"( void target() { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
