[clang] 3fed312 - [clang][dataflow]Propagate the result object location for CXXDefaultInitExpr. (#98490)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Jul 13 00:38:52 PDT 2024
Author: Samira Bazuzi
Date: 2024-07-13T00:38:49-07:00
New Revision: 3fed312d2bca7d44734ace75d18890675da0f89b
URL: https://github.com/llvm/llvm-project/commit/3fed312d2bca7d44734ace75d18890675da0f89b
DIFF: https://github.com/llvm/llvm-project/commit/3fed312d2bca7d44734ace75d18890675da0f89b.diff
LOG: [clang][dataflow]Propagate the result object location for CXXDefaultInitExpr. (#98490)
These are not "original initializers"; the single node underneath
represents the initializing node.
Added:
Modified:
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 7c88917faf9c6..f734168e647bd 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -15,6 +15,7 @@
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
@@ -414,8 +415,8 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
// lowest-level AST node that initializes a given object, and nothing
// below them can initialize the same object (or part of it).
if (isa<CXXConstructExpr>(E) || isa<CallExpr>(E) || isa<LambdaExpr>(E) ||
- isa<CXXDefaultArgExpr>(E) || isa<CXXDefaultInitExpr>(E) ||
- isa<CXXStdInitializerListExpr>(E) || isa<AtomicExpr>(E) ||
+ isa<CXXDefaultArgExpr>(E) || isa<CXXStdInitializerListExpr>(E) ||
+ isa<AtomicExpr>(E) ||
// We treat `BuiltinBitCastExpr` as an "original initializer" too as
// it may not even be casting from a record type -- and even if it is,
// the two objects are in general of unrelated type.
@@ -463,6 +464,11 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
return;
}
+ if (auto *DIE = dyn_cast<CXXDefaultInitExpr>(E)) {
+ PropagateResultObject(DIE->getExpr(), Loc);
+ return;
+ }
+
// All other expression nodes that propagate a record prvalue should have
// exactly one child.
SmallVector<Stmt *, 1> Children(E->child_begin(), E->child_end());
diff --git a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
index bd710a00c47ce..a4ac597bb06d6 100644
--- a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
@@ -21,6 +21,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <memory>
+#include <string>
namespace {
@@ -405,6 +406,42 @@ TEST_F(EnvironmentTest,
Contains(Member));
}
+// This is a repro of a failure case seen in the wild.
+TEST_F(EnvironmentTest, CXXDefaultInitExprResultObjIsWrappedExprResultObj) {
+ using namespace ast_matchers;
+
+ std::string Code = R"cc(
+ struct Inner {};
+
+ struct S {
+ S() {}
+
+ Inner i = {};
+ };
+ )cc";
+
+ auto Unit =
+ tooling::buildASTFromCodeWithArgs(Code, {"-fsyntax-only", "-std=c++11"});
+ auto &Context = Unit->getASTContext();
+
+ ASSERT_EQ(Context.getDiagnostics().getClient()->getNumErrors(), 0U);
+
+ auto Results =
+ match(cxxConstructorDecl(
+ hasAnyConstructorInitializer(cxxCtorInitializer(
+ withInitializer(expr().bind("default_init_expr")))))
+ .bind("ctor"),
+ Context);
+ const auto *Constructor = selectFirst<CXXConstructorDecl>("ctor", Results);
+ const auto *DefaultInit =
+ selectFirst<CXXDefaultInitExpr>("default_init_expr", Results);
+
+ Environment Env(DAContext, *Constructor);
+ Env.initialize();
+ EXPECT_EQ(&Env.getResultObjectLocation(*DefaultInit),
+ &Env.getResultObjectLocation(*DefaultInit->getExpr()));
+}
+
TEST_F(EnvironmentTest, Stmt) {
using namespace ast_matchers;
More information about the cfe-commits
mailing list