<div dir="ltr">I am trying to make the checker work for pointer escape. Since I track the status of objects using MemRegion, so I am using checkRegionChanges. I've observed something weird.<br><br>Suppose I have free functions whose definitions are not seen by current TU: void f(const S*); void g(S*);<br><br>1. Suppose I have<br>S s;<br>f(&s);<br>Then in checkRegionChanges, `s`'s region will appear in `explicit_regions` but not `regions`.<br><br>2. Suppose I have<br>S s;<br>g(&s);<br>Then in checkRegionChanges, `s`'s region will appear in both `explicit_regions` and `regions`.<br><br>Based on the above observations, if I want to remove `s` from GDM in case 2 but not 1, then I need to iterate over all entries in GDM and remove the ones that are sub-regions of any one in `region` variable, not `explicit_regions` variable. However, this doesn't work for the following case<br><br>3. If I have struct T { S s; D d; }; and U has some non-const member void D::h(); for the following call:<br>T t;<br>t.d.h();<br>Then in checkRegionChanges, `t.d` is in explicit_regions and `t` is in regions. So `t.s` will be removed from GDM if I check 'regions' variable, which is incorrect.<br><br>My question is, is case 1 a bug or a feature that `s` appears in `explicit_regions`? If it is by design, how what is the blessed way to distinguish the above cases? Thanks.<br><br>BTW: the code that causes the behavior is <br><a href="https://clang.llvm.org/doxygen/RegionStore_8cpp_source.html#l01256">https://clang.llvm.org/doxygen/RegionStore_8cpp_source.html#l01256</a><br>     if (const MemRegion *R = V.getAsRegion()) {<br>       if (TopLevelRegions)<br>         TopLevelRegions->push_back(R);<br>       W.AddToWorkList(R);<br>       continue;<br>     }<br>All regions are added to TopLevelRegions, without checking RegionAndSymbolInvalidationTraits::TK_PreserveContents.</div>