[cfe-commits] [patch] Subregion map
Ted Kremenek
kremenek at apple.com
Tue Mar 17 08:30:55 PDT 2009
On Mar 16, 2009, at 7:39 PM, Zhongxing Xu wrote:
> When we setup the subregion map, we should consider nested
> subregions. Consider the code:
>
> struct s1 {
> struct s2 {
> int d;
> } e;
> };
>
> void f(double timeout) {
> struct s1 a;
> a.e.d = (long) timeout;
> if (a.e.d == 10)
> a.e.d = 4;
> }
>
> Current implementation only setup subregion map from 'e' to 'd', but
> no map from 'a' to 'e'. So we lost the binding for a.e.d. The
> attached patch uses a worklist to record
> intermediate region roots which are subregions themselves.
Hi Zhongxing,
Looks good. One comment. Your patch expands to:
while (!IntermediateRoots.empty()) {
const MemRegion* R = IntermediateRoots.back();
IntermediateRoots.pop_back();
if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
if (SymReaper.isLive(Loc, VR->getDecl()))
RegionRoots.push_back(VR); // This is a live "root".
}
else {
// Get the super region for R.
const MemRegion* SuperR = cast<SubRegion>(R)->getSuperRegion();
// Get the current set of subregions for SuperR.
const SubRegionsTy* SRptr = SubRegMap.lookup(SuperR);
SubRegionsTy SR = SRptr ? *SRptr : SubRegF.GetEmptySet();
// Add R to the subregions of SuperR.
SubRegMap = SubRegMapF.Add(SubRegMap, SuperR, SubRegF.Add(SR,
R));
// Finally, check if SuperR is a VarRegion. We need to do this
// to also mark SuperR as a root (as it may not have a value
directly
// bound to it in the store).
if (const VarRegion* VR = dyn_cast<VarRegion>(SuperR)) {
if (SymReaper.isLive(Loc, VR->getDecl()))
RegionRoots.push_back(VR); // This is a live "root".
} else if (isa<SubRegion>(SuperR)) {
// We need to setup the subregion map of the super region of
the SuperR.
IntermediateRoots.push_back(SuperR);
}
}
}
With the worklist you added it seems like this code can now be
simplified:
while (!IntermediateRoots.empty()) {
const MemRegion* R = IntermediateRoots.back();
IntermediateRoots.pop_back();
if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
if (SymReaper.isLive(Loc, VR->getDecl()))
RegionRoots.push_back(VR); // This is a live "root".
}
else {
// Get the super region for R.
const MemRegion* SuperR = cast<SubRegion>(R)->getSuperRegion();
// Get the current set of subregions for SuperR.
const SubRegionsTy* SRptr = SubRegMap.lookup(SuperR);
SubRegionsTy SR = SRptr ? *SRptr : SubRegF.GetEmptySet();
// Add R to the subregions of SuperR.
SubRegMap = SubRegMapF.Add(SubRegMap, SuperR, SubRegF.Add(SR,
R));
// Handle super region.
if (isa<SubRegion>(SuperR) || isa<VarRegion>(VR))
ImmediateRoots.push_back(SuperR);
}
}
Here I have simplified the "recursive" case in the worklist by
enqueuing both VarRegions and SubRegions to the worklist in the "else"
block. This is a little nicer since the logic for handling VarRegions
(a base case) is now handled in one place.
More information about the cfe-commits
mailing list