https://github.com/ymand created https://github.com/llvm/llvm-project/pull/208726
Bug fix. In the transfer function (one of the cast cases), the loop adding synthetic fields to the derived record storage location was incorrectly nested inside the loop that iterates over modeled fields (`getModeledFields`). If the derived class has 0 modeled fields, `getModeledFields(Derived)` is empty. Consequently, synthetic fields were never added to the storage location, causing an assertion failure in `StorageLocation::getSyntheticField` when initializing field values. This patch moves the synthetic fields loop outside of the modeled fields loop and adds a regression unit test in `TransferTest.cpp`. >From 754a833d3c054b8bc496b9b0f505c9f98efd9728 Mon Sep 17 00:00:00 2001 From: Yitzhak Mandelbaum <[email protected]> Date: Fri, 10 Jul 2026 13:36:20 +0000 Subject: [PATCH] [clang][dataflow] Fix bug in transfer function of CK_BaseToDerived Bug fix. In the transfer function (one of the cast cases), the loop adding synthetic fields to the derived record storage location was incorrectly nested inside the loop that iterates over modeled fields (`getModeledFields`). If the derived class has 0 modeled fields, `getModeledFields(Derived)` is empty. Consequently, synthetic fields were never added to the storage location, causing an assertion failure in `StorageLocation::getSyntheticField` when initializing field values. This patch moves the synthetic fields loop outside of the modeled fields loop and adds a regression unit test in `TransferTest.cpp`. --- clang/lib/Analysis/FlowSensitive/Transfer.cpp | 10 +++---- .../Analysis/FlowSensitive/TransferTest.cpp | 27 +++++++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index d40843ff4ec43..bf4b245a3cf6f 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -371,12 +371,12 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> { } else { Loc->addChild(*Field, &Env.createStorageLocation(FieldType)); } + } - for (const auto &Entry : - Env.getDataflowAnalysisContext().getSyntheticFields(Derived)) { - Loc->addSyntheticField(Entry.getKey(), - Env.createStorageLocation(Entry.getValue())); - } + for (const auto &Entry : + Env.getDataflowAnalysisContext().getSyntheticFields(Derived)) { + Loc->addSyntheticField(Entry.getKey(), + Env.createStorageLocation(Entry.getValue())); } Env.initializeFieldsWithValues(*Loc, Derived); diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index e147f3dc7a195..501fa549afd43 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -3859,6 +3859,33 @@ TEST(TransferTest, StaticCastBaseToDerivedUnknown) { }); } +TEST(TransferTest, StaticCastBaseToDerivedWithSyntheticFieldsNoModeledFields) { + std::string Code = R"cc( + struct Base {}; + struct Derived : public Base {}; + void target(Base* BPtr) { + Derived* DPtr = static_cast<Derived*>(BPtr); + (void)DPtr; + // [[p]] + } + )cc"; + ASSERT_THAT_ERROR( + checkDataflowWithNoopAnalysis( + Code, ast_matchers::hasName("target"), + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, + ASTContext &ASTCtx) { + ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); + }, + {BuiltinOptions()}, LangStandard::lang_cxx17, + [](QualType Ty) -> llvm::StringMap<QualType> { + RecordDecl *RD = Ty->getAsRecordDecl(); + if (RD != nullptr && RD->getName() == "Derived") + return {{"synth", RD->getASTContext().IntTy}}; + return {}; + }), + llvm::Succeeded()); +} + TEST(TransferTest, MultipleConstructionsFromStaticCastsBaseToDerived) { std::string Code = R"cc( struct Base {}; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
