File tree Expand file tree Collapse file tree 2 files changed +27
-0
lines changed
lib/Analysis/FlowSensitive
unittests/Analysis/FlowSensitive Expand file tree Collapse file tree 2 files changed +27
-0
lines changed Original file line number Diff line number Diff line change @@ -147,6 +147,13 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
147
147
const Expr *RHS = S->getRHS ();
148
148
assert (RHS != nullptr );
149
149
150
+ // Do compound assignments up-front, as there are so many of them and we
151
+ // don't want to list all of them in the switch statement below.
152
+ // To avoid generating unnecessary values, we don't create a new value but
153
+ // instead leave it to the specific analysis to do this if desired.
154
+ if (S->isCompoundAssignmentOp ())
155
+ propagateStorageLocation (*S->getLHS (), *S, Env);
156
+
150
157
switch (S->getOpcode ()) {
151
158
case BO_Assign: {
152
159
auto *LHSLoc = Env.getStorageLocation (*LHS);
Original file line number Diff line number Diff line change @@ -3796,6 +3796,26 @@ TEST(TransferTest, Postincrement) {
3796
3796
});
3797
3797
}
3798
3798
3799
+ // We test just one of the compound assignment operators because we know the
3800
+ // code for propagating the storage location is shared among all of them.
3801
+ TEST (TransferTest, AddAssign) {
3802
+ std::string Code = R"(
3803
+ void target(int I) {
3804
+ int &IRef = (I += 1);
3805
+ // [[p]]
3806
+ }
3807
+ )" ;
3808
+ runDataflow (
3809
+ Code,
3810
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
3811
+ ASTContext &ASTCtx) {
3812
+ const Environment &Env = getEnvironmentAtAnnotation (Results, " p" );
3813
+
3814
+ EXPECT_EQ (&getLocForDecl (ASTCtx, Env, " IRef" ),
3815
+ &getLocForDecl (ASTCtx, Env, " I" ));
3816
+ });
3817
+ }
3818
+
3799
3819
TEST (TransferTest, CannotAnalyzeFunctionTemplate) {
3800
3820
std::string Code = R"(
3801
3821
template <typename T>
You can’t perform that action at this time.
0 commit comments