[clang] 3682e22 - [clang][dataflow] Improve handling of constructor initializers.
Yitzhak Mandelbaum via cfe-commits
cfe-commits at lists.llvm.org
Fri May 27 07:02:15 PDT 2022
Author: Yitzhak Mandelbaum
Date: 2022-05-27T13:54:11Z
New Revision: 3682e22ef404e1314ee1eab9daf6de99dc9ea8ee
URL: https://github.com/llvm/llvm-project/commit/3682e22ef404e1314ee1eab9daf6de99dc9ea8ee
DIFF: https://github.com/llvm/llvm-project/commit/3682e22ef404e1314ee1eab9daf6de99dc9ea8ee.diff
LOG: [clang][dataflow] Improve handling of constructor initializers.
Currently, we assert that `CXXCtorInitializer`s are field initializers. Replace
the assertion with an early return. Otherwise, we crash every time we process a
constructor with a non-field (e.g. base class) initializer.
Differential Revision: https://reviews.llvm.org/D126419
Added:
Modified:
clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
index ee1723dcd8cc..8a5d5ca386af 100644
--- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -257,6 +257,11 @@ static void transferCFGInitializer(const CFGInitializer &CfgInit,
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 @@ static void transferCFGInitializer(const CFGInitializer &CfgInit,
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,
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index dbf59bf69556..efea7797b45f 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -1296,6 +1296,49 @@ TEST_F(TransferTest, ClassMember) {
});
}
+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 {
More information about the cfe-commits
mailing list