diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -775,6 +775,11 @@ Env.setValueStrict(*S, Env.getBoolLiteralValue(S->getValue())); } + void VisitIntegerLiteral(const IntegerLiteral *S) { + if (Value *Val = Env.createValue(S->getType())) + Env.setValueStrict(*S, *Val); + } + void VisitParenExpr(const ParenExpr *S) { // The CFG does not contain `ParenExpr` as top-level statements in basic // blocks, however manual traversal to sub-expressions may encounter them. diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -811,6 +811,31 @@ }); } +TEST(TransferTest, BinaryOperatorAssignLiteral) { + std::string Code = R"( + void target() { + int Foo = 1; + // [[before]] + Foo = 2; + // [[after]] + } + )"; + runDataflow( + Code, + [](const llvm::StringMap> &Results, + ASTContext &ASTCtx) { + const Environment &Before = + getEnvironmentAtAnnotation(Results, "before"); + const Environment &After = getEnvironmentAtAnnotation(Results, "after"); + + const auto &ValBefore = + getValueForDecl(ASTCtx, Before, "Foo"); + const auto &ValAfter = + getValueForDecl(ASTCtx, After, "Foo"); + EXPECT_NE(&ValBefore, &ValAfter); + }); +} + TEST(TransferTest, VarDeclInitAssign) { std::string Code = R"( void target() {