mboehme updated this revision to Diff 539366. mboehme added a comment. Changes in response to review comments
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D154965/new/ https://reviews.llvm.org/D154965 Files: clang/lib/Analysis/FlowSensitive/Transfer.cpp clang/unittests/Analysis/FlowSensitive/TransferTest.cpp Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp =================================================================== --- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -2912,6 +2912,34 @@ } } +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 { Index: clang/lib/Analysis/FlowSensitive/Transfer.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -717,14 +717,15 @@ 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); } }
Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp =================================================================== --- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -2912,6 +2912,34 @@ } } +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 { Index: clang/lib/Analysis/FlowSensitive/Transfer.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -717,14 +717,15 @@ 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); } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits