aboutsummaryrefslogtreecommitdiff
path: root/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
diff options
context:
space:
mode:
authormartinboehme <mboehme@google.com>2024-03-08 08:19:02 +0100
committerGitHub <noreply@github.com>2024-03-08 08:19:02 +0100
commit2d539db246fd9d26201255b84d04dacf2782eddf (patch)
tree522da129e97e6eab5e0b8274c398a548281b03b7 /clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
parent23c658ac4183272221ef358575dca0d386096d36 (diff)
downloadllvm-2d539db246fd9d26201255b84d04dacf2782eddf.zip
llvm-2d539db246fd9d26201255b84d04dacf2782eddf.tar.gz
llvm-2d539db246fd9d26201255b84d04dacf2782eddf.tar.bz2
[clang][dataflow] When analyzing ctors, don't initialize fields of `*this` with values. (#84164)
This is the constructor's job, and we want to be able to test that it does this.
Diffstat (limited to 'clang/unittests/Analysis/FlowSensitive/TransferTest.cpp')
-rw-r--r--clang/unittests/Analysis/FlowSensitive/TransferTest.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index f534ccb..9fde417 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -1476,6 +1476,69 @@ TEST(TransferTest, BaseClassInitializer) {
llvm::Succeeded());
}
+TEST(TransferTest, FieldsDontHaveValuesInConstructor) {
+ // In a constructor, unlike in regular member functions, we don't want fields
+ // to be pre-initialized with values, because doing so is the job of the
+ // constructor.
+ std::string Code = R"(
+ struct target {
+ target() {
+ 0;
+ // [[p]]
+ // Mention the field so it is modeled;
+ Val;
+ }
+
+ int Val;
+ };
+ )";
+ runDataflow(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {
+ const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+ EXPECT_EQ(getFieldValue(Env.getThisPointeeStorageLocation(), "Val",
+ ASTCtx, Env),
+ nullptr);
+ });
+}
+
+TEST(TransferTest, FieldsDontHaveValuesInConstructorWithBaseClass) {
+ // See above, but for a class with a base class.
+ std::string Code = R"(
+ struct Base {
+ int BaseVal;
+ };
+
+ struct target : public Base {
+ target() {
+ 0;
+ // [[p]]
+ // Mention the fields so they are modeled.
+ BaseVal;
+ Val;
+ }
+
+ int Val;
+ };
+ )";
+ runDataflow(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {
+ const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+ // FIXME: The field of the base class should already have been
+ // initialized with a value by the base constructor. This test documents
+ // the current buggy behavior.
+ EXPECT_EQ(getFieldValue(Env.getThisPointeeStorageLocation(), "BaseVal",
+ ASTCtx, Env),
+ nullptr);
+ EXPECT_EQ(getFieldValue(Env.getThisPointeeStorageLocation(), "Val",
+ ASTCtx, Env),
+ nullptr);
+ });
+}
+
TEST(TransferTest, StructModeledFieldsWithAccessor) {
std::string Code = R"(
class S {