This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. mboehme marked an inline comment as done. Closed by commit rGd36324866ee1: [clang][dataflow] Initialize fields of anonymous records correctly. (authored by mboehme).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D153852/new/ https://reviews.llvm.org/D153852 Files: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp clang/lib/Analysis/FlowSensitive/Transfer.cpp clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.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 @@ -5483,4 +5483,35 @@ }); } +TEST(TransferTest, AnonymousStructWithInitializer) { + std::string Code = R"( + struct target { + target() { + (void)0; + // [[p]] + } + struct { + bool b = true; + }; + }; + )"; + runDataflow( + Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, + ASTContext &ASTCtx) { + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + const ValueDecl *BDecl = findValueDecl(ASTCtx, "b"); + const IndirectFieldDecl *IndirectField = + findIndirectFieldDecl(ASTCtx, "b"); + + auto *ThisLoc = + cast<AggregateStorageLocation>(Env.getThisPointeeStorageLocation()); + auto &AnonStruct = cast<AggregateStorageLocation>(ThisLoc->getChild( + *cast<ValueDecl>(IndirectField->chain().front()))); + + auto *B = cast<BoolValue>(Env.getValue(AnonStruct.getChild(*BDecl))); + ASSERT_TRUE(Env.flowConditionImplies(*B)); + }); +} + } // namespace Index: clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -366,27 +366,41 @@ assert(Init != nullptr); auto &Env = InputState.Env; - const auto &ThisLoc = + auto &ThisLoc = *cast<AggregateStorageLocation>(Env.getThisPointeeStorageLocation()); - const FieldDecl *Member = Init->getMember(); - if (Member == nullptr) - // Not a field initializer. + if (!Init->isAnyMemberInitializer()) + // FIXME: Handle base initialization return; auto *InitStmt = Init->getInit(); assert(InitStmt != nullptr); + const FieldDecl *Member = nullptr; + StorageLocation *MemberLoc = nullptr; + if (Init->isMemberInitializer()) { + Member = Init->getMember(); + MemberLoc = &ThisLoc.getChild(*Member); + } else { + IndirectFieldDecl *IndirectField = Init->getIndirectMember(); + assert(IndirectField != nullptr); + MemberLoc = &ThisLoc; + for (const auto *I : IndirectField->chain()) { + Member = cast<FieldDecl>(I); + MemberLoc = &cast<AggregateStorageLocation>(MemberLoc)->getChild(*Member); + } + } + assert(Member != nullptr); + assert(MemberLoc != nullptr); + if (Member->getType()->isReferenceType()) { auto *InitStmtLoc = Env.getStorageLocationStrict(*InitStmt); if (InitStmtLoc == nullptr) return; - auto &MemberLoc = ThisLoc.getChild(*Member); - Env.setValue(MemberLoc, Env.create<ReferenceValue>(*InitStmtLoc)); + Env.setValue(*MemberLoc, Env.create<ReferenceValue>(*InitStmtLoc)); } else if (auto *InitStmtVal = Env.getValueStrict(*InitStmt)) { - auto &MemberLoc = ThisLoc.getChild(*Member); - Env.setValue(MemberLoc, *InitStmtVal); + Env.setValue(*MemberLoc, *InitStmtVal); } } Index: clang/lib/Analysis/FlowSensitive/Transfer.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -153,7 +153,7 @@ Env.setStorageLocationStrict(To, *Loc); } -// Forwards the value or storage location of `From` to `To` in cases where +// Propagates the value or storage location of `From` to `To` in cases where // `From` may be either a glvalue or a prvalue. `To` must be a glvalue iff // `From` is a glvalue. static void propagateValueOrStorageLocation(const Expr &From, const Expr &To, @@ -572,18 +572,7 @@ void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) { const Expr *InitExpr = S->getExpr(); assert(InitExpr != nullptr); - - Value *InitExprVal = Env.getValue(*InitExpr, SkipPast::None); - if (InitExprVal == nullptr) - return; - - const FieldDecl *Field = S->getField(); - assert(Field != nullptr); - - auto &ThisLoc = - *cast<AggregateStorageLocation>(Env.getThisPointeeStorageLocation()); - auto &FieldLoc = ThisLoc.getChild(*Field); - Env.setValue(FieldLoc, *InitExprVal); + propagateValueOrStorageLocation(*InitExpr, *S, Env); } void VisitCXXConstructExpr(const CXXConstructExpr *S) { Index: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -227,8 +227,12 @@ // constructor-initializers. if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FuncDecl)) { for (const auto *Init : CtorDecl->inits()) { - if (const auto *M = Init->getAnyMember()) - Fields.insert(M); + if (Init->isMemberInitializer()) { + Fields.insert(Init->getMember()); + } else if (Init->isIndirectMemberInitializer()) { + for (const auto *I : Init->getIndirectMember()->chain()) + Fields.insert(cast<FieldDecl>(I)); + } const Expr *E = Init->getInit(); assert(E != nullptr); getFieldsGlobalsAndFuncs(*E, Fields, Vars, Funcs);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits