Skip to content

Commit 85f47fd

Browse files
authored
[clang][nullability] Improve modeling of ++/-- operators. (#96601)
We definitely know that these operations change the value of their operand, so clear out any value associated with it. We don't create a new value, instead leaving it to the analysis to do this if desired.
1 parent dfe80a7 commit 85f47fd

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-14
lines changed

clang/lib/Analysis/FlowSensitive/Transfer.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -391,17 +391,22 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
391391
}
392392
case UO_PreInc:
393393
case UO_PreDec:
394-
// Propagate the storage location, but don't create a new value; to
395-
// avoid generating unnecessary values, we leave it to the specific
396-
// analysis to do this if desired.
394+
// Propagate the storage location and clear out any value associated with
395+
// it (to represent the fact that the value has definitely changed).
396+
// To avoid generating unnecessary values, we leave it to the specific
397+
// analysis to create a new value if desired.
397398
propagateStorageLocation(*S->getSubExpr(), *S, Env);
399+
if (StorageLocation *Loc = Env.getStorageLocation(*S->getSubExpr()))
400+
Env.clearValue(*Loc);
398401
break;
399402
case UO_PostInc:
400403
case UO_PostDec:
401-
// Propagate the old value, but don't create a new value; to avoid
402-
// generating unnecessary values, we leave it to the specific analysis
403-
// to do this if desired.
404+
// Propagate the old value, then clear out any value associated with the
405+
// storage location (to represent the fact that the value has definitely
406+
// changed). See above for rationale.
404407
propagateValue(*S->getSubExpr(), *S, Env);
408+
if (StorageLocation *Loc = Env.getStorageLocation(*S->getSubExpr()))
409+
Env.clearValue(*Loc);
405410
break;
406411
default:
407412
break;

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3832,36 +3832,51 @@ TEST(TransferTest, AddrOfReference) {
38323832
TEST(TransferTest, Preincrement) {
38333833
std::string Code = R"(
38343834
void target(int I) {
3835+
(void)0; // [[before]]
38353836
int &IRef = ++I;
3836-
// [[p]]
3837+
// [[after]]
38373838
}
38383839
)";
38393840
runDataflow(
38403841
Code,
38413842
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
38423843
ASTContext &ASTCtx) {
3843-
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
3844+
const Environment &EnvBefore =
3845+
getEnvironmentAtAnnotation(Results, "before");
3846+
const Environment &EnvAfter =
3847+
getEnvironmentAtAnnotation(Results, "after");
38443848

3845-
EXPECT_EQ(&getLocForDecl(ASTCtx, Env, "IRef"),
3846-
&getLocForDecl(ASTCtx, Env, "I"));
3849+
EXPECT_EQ(&getLocForDecl(ASTCtx, EnvAfter, "IRef"),
3850+
&getLocForDecl(ASTCtx, EnvBefore, "I"));
3851+
3852+
const ValueDecl *IDecl = findValueDecl(ASTCtx, "I");
3853+
EXPECT_NE(EnvBefore.getValue(*IDecl), nullptr);
3854+
EXPECT_EQ(EnvAfter.getValue(*IDecl), nullptr);
38473855
});
38483856
}
38493857

38503858
TEST(TransferTest, Postincrement) {
38513859
std::string Code = R"(
38523860
void target(int I) {
3861+
(void)0; // [[before]]
38533862
int OldVal = I++;
3854-
// [[p]]
3863+
// [[after]]
38553864
}
38563865
)";
38573866
runDataflow(
38583867
Code,
38593868
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
38603869
ASTContext &ASTCtx) {
3861-
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
3870+
const Environment &EnvBefore =
3871+
getEnvironmentAtAnnotation(Results, "before");
3872+
const Environment &EnvAfter =
3873+
getEnvironmentAtAnnotation(Results, "after");
3874+
3875+
EXPECT_EQ(&getValueForDecl(ASTCtx, EnvBefore, "I"),
3876+
&getValueForDecl(ASTCtx, EnvAfter, "OldVal"));
38623877

3863-
EXPECT_EQ(&getValueForDecl(ASTCtx, Env, "OldVal"),
3864-
&getValueForDecl(ASTCtx, Env, "I"));
3878+
const ValueDecl *IDecl = findValueDecl(ASTCtx, "I");
3879+
EXPECT_EQ(EnvAfter.getValue(*IDecl), nullptr);
38653880
});
38663881
}
38673882

0 commit comments

Comments
 (0)