diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index e1a2606de8103..4c97e81184bba 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -717,14 +717,15 @@ class TransferVisitor : public ConstStmtVisitor { if (Type->isStructureOrClassType()) { std::vector 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(Val)->setChild(*Field, + Env.create(*Loc)); + } else if (Value *InitVal = Env.getValue(*Init, SkipPast::None)) cast(Val)->setChild(*Field, *InitVal); } } diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 254226fd6d3ee..a89ff8e7bc5ab 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> &Results, + ASTContext &ASTCtx) { + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + + const ValueDecl *RefFieldDecl = findValueDecl(ASTCtx, "RefField"); + + auto &ILoc = getLocForDecl(ASTCtx, Env, "i"); + auto &SLoc = getLocForDecl(ASTCtx, Env, "s"); + + auto &RefValue = + *cast(getFieldValue(&SLoc, *RefFieldDecl, Env)); + EXPECT_EQ(&RefValue.getReferentLoc(), &ILoc); + }); +} + TEST(TransferTest, AssignToUnionMember) { std::string Code = R"( union A {