Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6194229

Browse files
author
Tomasz Kamiński
committedOct 19, 2022
[analyzer] Make directly bounded LazyCompoundVal as lazily copied
Previously, `LazyCompoundVal` bindings to subregions referred by `LazyCopoundVals`, were not marked as //lazily copied//. This change returns `LazyCompoundVals` from `getInterestingValues()`, so their regions can be marked as //lazily copied// in `RemoveDeadBindingsWorker::VisitBinding()`. Depends on D134947 Authored by: Tomasz Kamiński <tomasz.kamiń[email protected]> Reviewed By: martong Differential Revision: https://reviews.llvm.org/D135136
1 parent a6b4204 commit 6194229

File tree

2 files changed

+26
-33
lines changed

2 files changed

+26
-33
lines changed
 

‎clang/lib/StaticAnalyzer/Core/RegionStore.cpp‎

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,10 @@ class RegionStoreManager : public StoreManager {
608608
/// The precise value of "interesting" is determined for the purposes of
609609
/// RegionStore's internal analysis. It must always contain all regions and
610610
/// symbols, but may omit constants and other kinds of SVal.
611+
///
612+
/// In contrast to compound values, LazyCompoundVals are also added
613+
/// to the 'interesting values' list in addition to the child interesting
614+
/// values.
611615
const SValListTy &getInterestingValues(nonloc::LazyCompoundVal LCV);
612616

613617
//===------------------------------------------------------------------===//
@@ -1032,12 +1036,11 @@ void InvalidateRegionsWorker::VisitBinding(SVal V) {
10321036
if (Optional<nonloc::LazyCompoundVal> LCS =
10331037
V.getAs<nonloc::LazyCompoundVal>()) {
10341038

1035-
const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
1036-
1037-
for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
1038-
E = Vals.end();
1039-
I != E; ++I)
1040-
VisitBinding(*I);
1039+
// `getInterestingValues()` returns SVals contained within LazyCompoundVals,
1040+
// so there is no need to visit them.
1041+
for (SVal V : RM.getInterestingValues(*LCS))
1042+
if (!isa<nonloc::LazyCompoundVal>(V))
1043+
VisitBinding(V);
10411044

10421045
return;
10431046
}
@@ -1290,15 +1293,10 @@ void RegionStoreManager::populateWorkList(InvalidateRegionsWorker &W,
12901293
if (Optional<nonloc::LazyCompoundVal> LCS =
12911294
V.getAs<nonloc::LazyCompoundVal>()) {
12921295

1293-
const SValListTy &Vals = getInterestingValues(*LCS);
1294-
1295-
for (SValListTy::const_iterator I = Vals.begin(),
1296-
E = Vals.end(); I != E; ++I) {
1297-
// Note: the last argument is false here because these are
1298-
// non-top-level regions.
1299-
if (const MemRegion *R = (*I).getAsRegion())
1296+
for (SVal S : getInterestingValues(*LCS))
1297+
if (const MemRegion *R = S.getAsRegion())
13001298
W.AddToWorkList(R);
1301-
}
1299+
13021300
continue;
13031301
}
13041302

@@ -2283,11 +2281,9 @@ RegionStoreManager::getInterestingValues(nonloc::LazyCompoundVal LCV) {
22832281
if (V.isUnknownOrUndef() || V.isConstant())
22842282
continue;
22852283

2286-
if (Optional<nonloc::LazyCompoundVal> InnerLCV =
2287-
V.getAs<nonloc::LazyCompoundVal>()) {
2284+
if (auto InnerLCV = V.getAs<nonloc::LazyCompoundVal>()) {
22882285
const SValListTy &InnerList = getInterestingValues(*InnerLCV);
22892286
List.insert(List.end(), InnerList.begin(), InnerList.end());
2290-
continue;
22912287
}
22922288

22932289
List.push_back(V);
@@ -2835,20 +2831,17 @@ void RemoveDeadBindingsWorker::VisitCluster(const MemRegion *baseR,
28352831
}
28362832

28372833
void RemoveDeadBindingsWorker::VisitBinding(SVal V) {
2838-
// Is it a LazyCompoundVal? All referenced regions are live as well.
2839-
if (Optional<nonloc::LazyCompoundVal> LCS =
2840-
V.getAs<nonloc::LazyCompoundVal>()) {
2841-
// TODO: Make regions referred to by `lazyCompoundVals` that are bound to
2842-
// subregions of the `LCS.getRegion()` also lazily copied.
2843-
if (const MemRegion *R = LCS->getRegion())
2844-
SymReaper.markLazilyCopied(R);
2845-
2846-
const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
2847-
2848-
for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
2849-
E = Vals.end();
2850-
I != E; ++I)
2851-
VisitBinding(*I);
2834+
// Is it a LazyCompoundVal? All referenced regions are live as well.
2835+
// The LazyCompoundVal itself is not live but should be readable.
2836+
if (auto LCS = V.getAs<nonloc::LazyCompoundVal>()) {
2837+
SymReaper.markLazilyCopied(LCS->getRegion());
2838+
2839+
for (SVal V : RM.getInterestingValues(*LCS)) {
2840+
if (auto DepLCS = V.getAs<nonloc::LazyCompoundVal>())
2841+
SymReaper.markLazilyCopied(DepLCS->getRegion());
2842+
else
2843+
VisitBinding(V);
2844+
}
28522845

28532846
return;
28542847
}

‎clang/test/Analysis/trivial-copy-struct.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ void nestedLazyCompoundVal(List* n) {
9292
}
9393
if (!n->next) {
9494
if (w->head.next) {
95-
// FIXME: Unreachable, w->head is a copy of *n, therefore
95+
// Unreachable, w->head is a copy of *n, therefore
9696
// w->head.next and n->next are equal
97-
clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
97+
clang_analyzer_warnIfReached(); // no-warning: unreachable
9898
}
9999
}
100100
delete w;

0 commit comments

Comments
 (0)
Please sign in to comment.