Szelethus marked an inline comment as done.
Szelethus added inline comments.


================
Comment at: lib/StaticAnalyzer/Checkers/MoveChecker.cpp:528
     ArrayRef<const MemRegion *> ExplicitRegions,
     ArrayRef<const MemRegion *> Regions, const LocationContext *LCtx,
     const CallEvent *Call) const {
----------------
NoQ wrote:
> Szelethus wrote:
> > This isn't specific to this revision, but I find the parameter name 
> > `Regions` way too vague. Maybe `ImplicitRegions`?
> How about these?
Awesome, thanks! :)


================
Comment at: lib/StaticAnalyzer/Checkers/MoveChecker.cpp:540-542
+    // Explicit regions are the regions passed into the call directly, but
+    // not all of them end up being invalidated. The ones that do appear in
+    // the Regions array as well.
----------------
NoQ wrote:
> NoQ wrote:
> > Szelethus wrote:
> > > Really? Then I guess this needs to be updated in 
> > > `CheckerDocumentation.cpp`:
> > > 
> > > ```
> > >   /// \param ExplicitRegions The regions explicitly requested for 
> > > invalidation.
> > >   ///        For a function call, this would be the arguments. For a 
> > > bind, this
> > >   ///        would be the region being bound to.
> > > ```
> > > 
> > > To me, this clearly indicates that the elements of `ExplicitRegions` will 
> > > be invalidated. Does "requested for" really just mean "requested for 
> > > potential"? Since this happens //before// any invalidation, it could 
> > > easily be interpreted as "invalidated after the end of the callback".
> > The callback fires after invalidation - cf. 
> > `ProgramState::invalidateRegionsImpl`. Note that the `if (Eng)` condition 
> > is always true, because how the heck were we supposed to run path-sensitive 
> > analysis without `ExprEngine`.
> > 
> > The terminology is really weird here because we the word "invalidation" has 
> > too many meanings. Essentially, `ExplicitRegions` are regions that were 
> > specifically requested for invalidation, but it is up to the `CallEvent` / 
> > `ProgramState` / `StoreManager` (depending on which `invalidateRegions()` 
> > was called) to decide what invalidation means in this case by filling in 
> > the `RegionAndSymbolInvalidationTraits` map.
> > 
> > For regions that represent values of const pointers/references directly 
> > passed into the function, `CallEvent` decides to set the 
> > `TK_PreserveContents` trait, which says "invalidate the region but keep its 
> > contents intact". It would still perform other forms of invalidation on 
> > that region, say, pointer escape: if there are pointer values written down 
> > somewhere within that region, checkers need to stop tracking them.
> > 
> > Now, the callback never said that it has something to do with 
> > "invalidation". Instead, it is about "region changes", which means changes 
> > of the region's contents in the Store. This doesn't necessarily happen due 
> > to invalidation; it may also happen while evaluating a simple assignment in 
> > the program, as we see in the newly added `testUpdateField()` test. And, as 
> > we've seen above, not every "invalidation" changes contents of the region.
> > 
> > Similarly, `TK_SuppressEscape` would suppress the `checkPointerEscape()` 
> > callback for the region, but will not suppress `checkRegionChanges()` for 
> > that (non-explicit) region.
> > 
> > Therefore we end up in a weird situation when some regions were requested 
> > to be invalidated but never were actually invalidated in terms of the 
> > Store. It kinda  makes sense, but i hate it anyway.  The 
> > `checkRegionChanges()` callback is hard to understand and hard to use and 
> > too general and has too much stuff stuffed into it. `checkPointerEscape` is 
> > an easier-to-use fork of it, but it doesn't cover the use case of checkers 
> > that track objects via regions. I suspect that the right solution here is 
> > to start tracking objects as "symbols", i.e., assign a unique opaque ID to 
> > every state through which every object in the program goes (regardless of 
> > which object it is) and use that as keys in the map. That should remove the 
> > stress of dealing with invalidation from C++ checkers that need to track 
> > objects opaquely. The problem won't magically disappear, as we still need 
> > to identify when exactly does the state change, but an additional level of 
> > indirection (Region -> ID -> CheckerState instead of just Region -> 
> > CheckerState) allows us to decompose it into smaller parts and de-duplicate 
> > some of this work.
> > 
> > But regardless of that, it is still weird that `ExplicitRegions` is not a 
> > sub-set of `Regions`. We need to either document it or fix it, and for some 
> > reason i prefer the latter. In particular, the only checker that actually 
> > actively acts upon `ExplicitRegions` when they're const is 
> > `RetainCountChecker`, but in fact people don't ever use `const` in stuff 
> > that it checks, it just isn't idiomatic.
> Another funny thing about `RegionAndSymbolInvalidationTraits`  is that it 
> races when the same region is passed both via const pointer and a non-const 
> pointer. The region will be invalidated or not depending on which one goes in 
> first. We really need to fix it.
Oh okay! Thanks for the detailed explanation! I share your concern with this 
being a little messy.

> We need to either document it or fix it, and for some reason i prefer the 
> latter. 
Me too.


================
Comment at: lib/StaticAnalyzer/Checkers/MoveChecker.cpp:56
                      ArrayRef<const MemRegion *> ExplicitRegions,
                      ArrayRef<const MemRegion *> Regions,
                      const LocationContext *LCtx, const CallEvent *Call) const;
----------------
This should be `RequestedRegions` too then :)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55289/new/

https://reviews.llvm.org/D55289



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to