@@ -3902,6 +3902,36 @@ TEST(TransferTest, ContextSensitiveOptionDisabled) {
3902
3902
{TransferOptions{/* .ContextSensitiveOpts=*/ llvm::None}});
3903
3903
}
3904
3904
3905
+ TEST (TransferTest, ContextSensitiveDepthZero) {
3906
+ std::string Code = R"(
3907
+ bool GiveBool();
3908
+ void SetBool(bool &Var) { Var = true; }
3909
+
3910
+ void target() {
3911
+ bool Foo = GiveBool();
3912
+ SetBool(Foo);
3913
+ // [[p]]
3914
+ }
3915
+ )" ;
3916
+ runDataflow (Code,
3917
+ [](llvm::ArrayRef<
3918
+ std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
3919
+ Results,
3920
+ ASTContext &ASTCtx) {
3921
+ ASSERT_THAT (Results, ElementsAre (Pair (" p" , _)));
3922
+ const Environment &Env = Results[0 ].second .Env ;
3923
+
3924
+ const ValueDecl *FooDecl = findValueDecl (ASTCtx, " Foo" );
3925
+ ASSERT_THAT (FooDecl, NotNull ());
3926
+
3927
+ auto &FooVal =
3928
+ *cast<BoolValue>(Env.getValue (*FooDecl, SkipPast::None));
3929
+ EXPECT_FALSE (Env.flowConditionImplies (FooVal));
3930
+ EXPECT_FALSE (Env.flowConditionImplies (Env.makeNot (FooVal)));
3931
+ },
3932
+ {TransferOptions{ContextSensitiveOptions{/* .Depth=*/ 0 }}});
3933
+ }
3934
+
3905
3935
TEST (TransferTest, ContextSensitiveSetTrue) {
3906
3936
std::string Code = R"(
3907
3937
bool GiveBool();
@@ -4000,7 +4030,7 @@ TEST(TransferTest, ContextSensitiveSetBothTrueAndFalse) {
4000
4030
{TransferOptions{ContextSensitiveOptions{}}});
4001
4031
}
4002
4032
4003
- TEST (TransferTest, ContextSensitiveSetTwoLayers ) {
4033
+ TEST (TransferTest, ContextSensitiveSetTwoLayersDepthOne ) {
4004
4034
std::string Code = R"(
4005
4035
bool GiveBool();
4006
4036
void SetBool1(bool &Var) { Var = true; }
@@ -4028,7 +4058,146 @@ TEST(TransferTest, ContextSensitiveSetTwoLayers) {
4028
4058
EXPECT_FALSE (Env.flowConditionImplies (FooVal));
4029
4059
EXPECT_FALSE (Env.flowConditionImplies (Env.makeNot (FooVal)));
4030
4060
},
4031
- {TransferOptions{ContextSensitiveOptions{}}});
4061
+ {TransferOptions{ContextSensitiveOptions{/* .Depth=*/ 1 }}});
4062
+ }
4063
+
4064
+ TEST (TransferTest, ContextSensitiveSetTwoLayersDepthTwo) {
4065
+ std::string Code = R"(
4066
+ bool GiveBool();
4067
+ void SetBool1(bool &Var) { Var = true; }
4068
+ void SetBool2(bool &Var) { SetBool1(Var); }
4069
+
4070
+ void target() {
4071
+ bool Foo = GiveBool();
4072
+ SetBool2(Foo);
4073
+ // [[p]]
4074
+ }
4075
+ )" ;
4076
+ runDataflow (Code,
4077
+ [](llvm::ArrayRef<
4078
+ std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
4079
+ Results,
4080
+ ASTContext &ASTCtx) {
4081
+ ASSERT_THAT (Results, ElementsAre (Pair (" p" , _)));
4082
+ const Environment &Env = Results[0 ].second .Env ;
4083
+
4084
+ const ValueDecl *FooDecl = findValueDecl (ASTCtx, " Foo" );
4085
+ ASSERT_THAT (FooDecl, NotNull ());
4086
+
4087
+ auto &FooVal =
4088
+ *cast<BoolValue>(Env.getValue (*FooDecl, SkipPast::None));
4089
+ EXPECT_TRUE (Env.flowConditionImplies (FooVal));
4090
+ },
4091
+ {TransferOptions{ContextSensitiveOptions{/* .Depth=*/ 2 }}});
4092
+ }
4093
+
4094
+ TEST (TransferTest, ContextSensitiveSetThreeLayersDepthTwo) {
4095
+ std::string Code = R"(
4096
+ bool GiveBool();
4097
+ void SetBool1(bool &Var) { Var = true; }
4098
+ void SetBool2(bool &Var) { SetBool1(Var); }
4099
+ void SetBool3(bool &Var) { SetBool2(Var); }
4100
+
4101
+ void target() {
4102
+ bool Foo = GiveBool();
4103
+ SetBool3(Foo);
4104
+ // [[p]]
4105
+ }
4106
+ )" ;
4107
+ runDataflow (Code,
4108
+ [](llvm::ArrayRef<
4109
+ std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
4110
+ Results,
4111
+ ASTContext &ASTCtx) {
4112
+ ASSERT_THAT (Results, ElementsAre (Pair (" p" , _)));
4113
+ const Environment &Env = Results[0 ].second .Env ;
4114
+
4115
+ const ValueDecl *FooDecl = findValueDecl (ASTCtx, " Foo" );
4116
+ ASSERT_THAT (FooDecl, NotNull ());
4117
+
4118
+ auto &FooVal =
4119
+ *cast<BoolValue>(Env.getValue (*FooDecl, SkipPast::None));
4120
+ EXPECT_FALSE (Env.flowConditionImplies (FooVal));
4121
+ EXPECT_FALSE (Env.flowConditionImplies (Env.makeNot (FooVal)));
4122
+ },
4123
+ {TransferOptions{ContextSensitiveOptions{/* .Depth=*/ 2 }}});
4124
+ }
4125
+
4126
+ TEST (TransferTest, ContextSensitiveSetThreeLayersDepthThree) {
4127
+ std::string Code = R"(
4128
+ bool GiveBool();
4129
+ void SetBool1(bool &Var) { Var = true; }
4130
+ void SetBool2(bool &Var) { SetBool1(Var); }
4131
+ void SetBool3(bool &Var) { SetBool2(Var); }
4132
+
4133
+ void target() {
4134
+ bool Foo = GiveBool();
4135
+ SetBool3(Foo);
4136
+ // [[p]]
4137
+ }
4138
+ )" ;
4139
+ runDataflow (Code,
4140
+ [](llvm::ArrayRef<
4141
+ std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
4142
+ Results,
4143
+ ASTContext &ASTCtx) {
4144
+ ASSERT_THAT (Results, ElementsAre (Pair (" p" , _)));
4145
+ const Environment &Env = Results[0 ].second .Env ;
4146
+
4147
+ const ValueDecl *FooDecl = findValueDecl (ASTCtx, " Foo" );
4148
+ ASSERT_THAT (FooDecl, NotNull ());
4149
+
4150
+ auto &FooVal =
4151
+ *cast<BoolValue>(Env.getValue (*FooDecl, SkipPast::None));
4152
+ EXPECT_TRUE (Env.flowConditionImplies (FooVal));
4153
+ },
4154
+ {TransferOptions{ContextSensitiveOptions{/* .Depth=*/ 3 }}});
4155
+ }
4156
+
4157
+ TEST (TransferTest, ContextSensitiveMutualRecursion) {
4158
+ std::string Code = R"(
4159
+ bool Pong(bool X, bool Y);
4160
+
4161
+ bool Ping(bool X, bool Y) {
4162
+ if (X) {
4163
+ return Y;
4164
+ } else {
4165
+ return Pong(!X, Y);
4166
+ }
4167
+ }
4168
+
4169
+ bool Pong(bool X, bool Y) {
4170
+ if (Y) {
4171
+ return X;
4172
+ } else {
4173
+ return Ping(X, !Y);
4174
+ }
4175
+ }
4176
+
4177
+ void target() {
4178
+ bool Foo = Ping(false, false);
4179
+ // [[p]]
4180
+ }
4181
+ )" ;
4182
+ runDataflow (Code,
4183
+ [](llvm::ArrayRef<
4184
+ std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
4185
+ Results,
4186
+ ASTContext &ASTCtx) {
4187
+ ASSERT_THAT (Results, ElementsAre (Pair (" p" , _)));
4188
+ // The analysis doesn't crash...
4189
+ const Environment &Env = Results[0 ].second .Env ;
4190
+
4191
+ const ValueDecl *FooDecl = findValueDecl (ASTCtx, " Foo" );
4192
+ ASSERT_THAT (FooDecl, NotNull ());
4193
+
4194
+ auto &FooVal =
4195
+ *cast<BoolValue>(Env.getValue (*FooDecl, SkipPast::None));
4196
+ // ... but it also can't prove anything here.
4197
+ EXPECT_FALSE (Env.flowConditionImplies (FooVal));
4198
+ EXPECT_FALSE (Env.flowConditionImplies (Env.makeNot (FooVal)));
4199
+ },
4200
+ {TransferOptions{ContextSensitiveOptions{/* .Depth=*/ 4 }}});
4032
4201
}
4033
4202
4034
4203
TEST (TransferTest, ContextSensitiveSetMultipleLines) {
0 commit comments