[PATCH] D97183: [analyzer] Add NoteTag for smart-ptr get()

Artem Dergachev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 9 14:05:08 PST 2021


NoQ added a comment.

> why does this not work?

How does this not work? What does it say?

> what is tracking mode for an ExplodedNode?

Mmm yeah, in hindsight i should have explained it much more.

First of all, we have "bug visitors". They are the entity that adds notes to bug reports. Note tags are a new way to add notes to the bug report but it's still the same visitors under the hood, i.e. there's visitor that scans note tags and invokes their callback to produce notes. These visitors scan the report from bottom to top. They typically emit note whenever something changes in program state. For instance, if an interesting pointer symbol in the program state changes its status from "allocated" to "release" (i.e., the visitor was so far only seeing nodes in which it was released but now it encounters the first node in which it's not released yet) then it adds a note "pointer was released" which is relevant for use-after-free warnings.

Now, sometimes we have to emit notes with respect to values that //aren't symbols//. For instance, in null dereference bugs we have to explain the movement of a value that's a plain and simple null pointer. Unlike symbols who each have unique identity that captures their backstory and properties, such "concrete" values are indistinguishable from each other. If we see a null in the older state and a null in a newer state, we can't tell if it's the same null or a different null. This makes it much harder to explain the journey a specific null value has undertaken in order to end up in our pointer that we've ended up dereferencing.

This is where `trackExpressionValue` comes in. It knows how to track concrete values such as Null or Undefined. The way it works is that it tracks something in the state that corresponds to that null value but does have an identity, typically either memory regions ("the null pointer is currently stored in this variable") or expressions ("the null pointer is currently being returned from this call expression"). Neither memory regions nor (especially!) expressions are guaranteed to stay the same throughout the entire journey so we have to skip from one to the other in order to keep tracking our null pointer (say, "the null pointer was returned from a call expression which acts as an initializer to a variable; now we can stop tracking the variable and start tracking the call expression"). This is what I referred to as changing modes. It's also very clear from the static analyzer code where the mode changes: namely, `trackExpressionValue` is not a single visitor but a combination of visitors that //recursively attach new instances of themselves to the report as they ascend it//. For instance, in the above example a visitor that tracks a variable would finish and attach a new visitor that tracks a call expression.

So basically i suspect that the act of reattaching the visitor could be documented through interestingness for your checker to pick up. That would allow you to query whether the call-expression `P.get()` returns an interesting null value as opposed to a dull, ordinary null value that's unrelated to the report.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D97183



More information about the cfe-commits mailing list