This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG3682e22ef404: [clang][dataflow] Improve handling of constructor initializers. (authored by ymandel).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D126419/new/ https://reviews.llvm.org/D126419 Files: 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 @@ -1296,6 +1296,49 @@ }); } +TEST_F(TransferTest, BaseClassInitializer) { + using ast_matchers::cxxConstructorDecl; + using ast_matchers::hasName; + using ast_matchers::ofClass; + + std::string Code = R"( + class A { + public: + A(int I) : Bar(I) {} + int Bar; + }; + + class B : public A { + public: + B(int I) : A(I) { + (void)0; + // [[p]] + } + }; + )"; + ASSERT_THAT_ERROR( + test::checkDataflow<NoopAnalysis>( + Code, cxxConstructorDecl(ofClass(hasName("B"))), + [](ASTContext &C, Environment &) { + return NoopAnalysis(C, /*ApplyBuiltinTransfer=*/true); + }, + [](llvm::ArrayRef< + std::pair<std::string, DataflowAnalysisState<NoopLattice>>> + Results, + ASTContext &ASTCtx) { + // Regression test to verify that base-class initializers do not + // trigger an assertion. If we add support for such initializers in + // the future, we can expand this test to check more specific + // properties. + EXPECT_THAT(Results, ElementsAre(Pair("p", _))); + }, + {"-fsyntax-only", "-fno-delayed-template-parsing", + "-std=" + std::string(LangStandard::getLangStandardForKind( + LangStandard::lang_cxx17) + .getName())}), + llvm::Succeeded()); +} + TEST_F(TransferTest, ReferenceMember) { std::string Code = R"( struct A { Index: clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -257,6 +257,11 @@ const CXXCtorInitializer *Initializer = CfgInit.getInitializer(); assert(Initializer != nullptr); + const FieldDecl *Member = Initializer->getMember(); + if (Member == nullptr) + // Not a field initializer. + return; + auto *InitStmt = Initializer->getInit(); assert(InitStmt != nullptr); @@ -269,9 +274,6 @@ if (InitStmtVal == nullptr) return; - const FieldDecl *Member = Initializer->getMember(); - assert(Member != nullptr); - if (Member->getType()->isReferenceType()) { auto &MemberLoc = ThisLoc.getChild(*Member); State.Env.setValue(MemberLoc,
Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp =================================================================== --- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -1296,6 +1296,49 @@ }); } +TEST_F(TransferTest, BaseClassInitializer) { + using ast_matchers::cxxConstructorDecl; + using ast_matchers::hasName; + using ast_matchers::ofClass; + + std::string Code = R"( + class A { + public: + A(int I) : Bar(I) {} + int Bar; + }; + + class B : public A { + public: + B(int I) : A(I) { + (void)0; + // [[p]] + } + }; + )"; + ASSERT_THAT_ERROR( + test::checkDataflow<NoopAnalysis>( + Code, cxxConstructorDecl(ofClass(hasName("B"))), + [](ASTContext &C, Environment &) { + return NoopAnalysis(C, /*ApplyBuiltinTransfer=*/true); + }, + [](llvm::ArrayRef< + std::pair<std::string, DataflowAnalysisState<NoopLattice>>> + Results, + ASTContext &ASTCtx) { + // Regression test to verify that base-class initializers do not + // trigger an assertion. If we add support for such initializers in + // the future, we can expand this test to check more specific + // properties. + EXPECT_THAT(Results, ElementsAre(Pair("p", _))); + }, + {"-fsyntax-only", "-fno-delayed-template-parsing", + "-std=" + std::string(LangStandard::getLangStandardForKind( + LangStandard::lang_cxx17) + .getName())}), + llvm::Succeeded()); +} + TEST_F(TransferTest, ReferenceMember) { std::string Code = R"( struct A { Index: clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -257,6 +257,11 @@ const CXXCtorInitializer *Initializer = CfgInit.getInitializer(); assert(Initializer != nullptr); + const FieldDecl *Member = Initializer->getMember(); + if (Member == nullptr) + // Not a field initializer. + return; + auto *InitStmt = Initializer->getInit(); assert(InitStmt != nullptr); @@ -269,9 +274,6 @@ if (InitStmtVal == nullptr) return; - const FieldDecl *Member = Initializer->getMember(); - assert(Member != nullptr); - if (Member->getType()->isReferenceType()) { auto &MemberLoc = ThisLoc.getChild(*Member); State.Env.setValue(MemberLoc,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits