Author: Martin Braenne Date: 2023-07-12T04:52:30Z New Revision: bd9b57de4ff7c65be0d69179232ba2d5fe832195
URL: https://github.com/llvm/llvm-project/commit/bd9b57de4ff7c65be0d69179232ba2d5fe832195 DIFF: https://github.com/llvm/llvm-project/commit/bd9b57de4ff7c65be0d69179232ba2d5fe832195.diff LOG: [clang][dataflow] Fix initializing a reference field with an `InitListExpr`. I added a test for this as the ongoing migration to strict handling of value categories (see https://discourse.llvm.org/t/70086) will change the code that handles this case. It turns out we already didn't handle this correctly, so I fixed the existing implementation. Depends On D154961 Reviewed By: xazax.hun Differential Revision: https://reviews.llvm.org/D154965 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 e1a2606de81033..4c97e81184bba3 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -717,14 +717,15 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> { if (Type->isStructureOrClassType()) { std::vector<FieldDecl *> Fields = getFieldsForInitListExpr(Type->getAsRecordDecl()); - for (auto It : llvm::zip(Fields, S->inits())) { - const FieldDecl *Field = std::get<0>(It); + for (auto [Field, Init] : llvm::zip(Fields, S->inits())) { assert(Field != nullptr); - - const Expr *Init = std::get<1>(It); assert(Init != nullptr); - if (Value *InitVal = Env.getValue(*Init, SkipPast::None)) + if (Field->getType()->isReferenceType()) { + if (StorageLocation *Loc = Env.getStorageLocationStrict(*Init)) + cast<StructValue>(Val)->setChild(*Field, + Env.create<ReferenceValue>(*Loc)); + } else if (Value *InitVal = Env.getValue(*Init, SkipPast::None)) cast<StructValue>(Val)->setChild(*Field, *InitVal); } } diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 254226fd6d3ee9..a89ff8e7bc5ab5 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -2912,6 +2912,34 @@ TEST(TransferTest, AggregateInitialization) { } } +TEST(TransferTest, AggregateInitializationReferenceField) { + std::string Code = R"( + struct S { + int &RefField; + }; + + void target(int i) { + S s = { i }; + /*[[p]]*/ + } + )"; + runDataflow( + Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, + ASTContext &ASTCtx) { + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + + const ValueDecl *RefFieldDecl = findValueDecl(ASTCtx, "RefField"); + + auto &ILoc = getLocForDecl<StorageLocation>(ASTCtx, Env, "i"); + auto &SLoc = getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "s"); + + auto &RefValue = + *cast<ReferenceValue>(getFieldValue(&SLoc, *RefFieldDecl, Env)); + EXPECT_EQ(&RefValue.getReferentLoc(), &ILoc); + }); +} + TEST(TransferTest, AssignToUnionMember) { std::string Code = R"( union A { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits