diff options
author | martinboehme <mboehme@google.com> | 2024-03-08 08:19:02 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-08 08:19:02 +0100 |
commit | 2d539db246fd9d26201255b84d04dacf2782eddf (patch) | |
tree | 522da129e97e6eab5e0b8274c398a548281b03b7 /clang/unittests/Analysis/FlowSensitive/TransferTest.cpp | |
parent | 23c658ac4183272221ef358575dca0d386096d36 (diff) | |
download | llvm-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.cpp | 63 |
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 { |