mboehme created this revision. Herald added subscribers: martong, xazax.hun. Herald added a reviewer: NoQ. Herald added a project: All. mboehme requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
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 <https://reviews.llvm.org/D154961> Repository: rG LLVM Github Monorepo 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 @@ -724,7 +724,11 @@ 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 @@ -724,7 +724,11 @@ 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