[clang] 26d1c4f - [clang][dataflow] Fix bug in transfer function of CK_BaseToDerived (#208726)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 10 07:25:23 PDT 2026
Author: Yitzhak Mandelbaum
Date: 2026-07-10T10:25:18-04:00
New Revision: 26d1c4f05ad9b715336a1cdc8be9257f6e30038d
URL: https://github.com/llvm/llvm-project/commit/26d1c4f05ad9b715336a1cdc8be9257f6e30038d
DIFF: https://github.com/llvm/llvm-project/commit/26d1c4f05ad9b715336a1cdc8be9257f6e30038d.diff
LOG: [clang][dataflow] Fix bug in transfer function of CK_BaseToDerived (#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`.
Added:
Modified:
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Removed:
################################################################################
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 {};
More information about the cfe-commits
mailing list