aboutsummaryrefslogtreecommitdiff
path: root/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
diff options
context:
space:
mode:
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 {