This is an archive of the discontinued LLVM Phabricator instance.

Add LocationContext to members of check::RegionChanges
AbandonedPublic

Authored by NoQ on Nov 13 2016, 7:43 AM.

Details

Summary

Hi,

I've been working on a checker that uses RegionChanges interface and needed to access to LocationContext. Another change is an easy way to obtain arguments' SVals from StackFrameCtx, with which the function/method has been called. In my opinion having that might prove useful for creating future checkers so I publish it here for review and discussion. Obvoiusly, this needs some improvement, but I'll be more than happy to hear community's opinion about the current version, as I wasn't sure if my changes fit into architecture etc.

Also: this is my first public contribution to clang. so if there are any annoying aspects of it (like the list of subscribers being to broad, bad forma, wrong metadata etc.) - sorry!

Diff Detail

Event Timeline

k-wisniewski retitled this revision from to Add LocationContext to members of check::RegionChanges.
k-wisniewski updated this object.
k-wisniewski added a subscriber: cfe-commits.
NoQ added a subscriber: NoQ.Nov 14 2016, 8:01 AM

Hi Krzysztof!
This change seems useful: I can imagine the situation where we want to ask current LocationContext in this callback. The change looks pretty intrusive but I mostly agree with it. Initially, I have some questions about the implementation of getArgSVal() function (inline comments). I'll add more comments later.

include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
735

Maybe we should put a check that requested StackFrame is our StackFrame or our parent StackFrame here?

741

Unfortunately, this code does not consider the fact that argument values may be overwritten. If we want to get initial values, we should find another way.

NoQ added a comment.Nov 14 2016, 11:37 AM

Welcome to phabricator! I agree that having the location context in this callback is useful, and i'm all for reducing boilerplate in various checkers through better API.

include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
231

Because this API becomes more complicated, i think we should add some docstrings here, explaining the meaning of the location context parameter, in particular.

733

Indent.

741

Uhm, yeah, this is in fact a problem!

The purpose of this code is, in fact, to construct SymbolRegionValue for the parameter, so it is equivalent to calling SValBuilder::getRegionValueSymbolVal() over the parameter region, as long as the current StoreManager implementation remains unquestioned.

We could also ask StoreManager to provide a binding for this region from an empty store, maybe extend its API to allow such queries, this would remove the layering violation.

Because this topic getting is rather complicated, it might have been better to make a separate review for this change, originally (no problem now that most of the interested people have already had a look).

NoQ added inline comments.Nov 14 2016, 8:12 PM
include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
735

Hmm. We should probably add a similar check to getSVal(Ex, LCtx)!- and also check that Ex is an active expression.

Unfortunately, we do not know the current location context within any of these methods, not sure how to implement that.

zaks.anna edited edge metadata.Nov 14 2016, 11:51 PM

Hi and welcome to the project!

This patch definitely looks quite complex for a first contribution, so great job at digging through the analyzer internals!

One higher level comment I have is that you should try and split patches whenever possible. For example, in the description, you mention that the patch contains 2 changes:

  • extending RegionChanges interface with LocationContext
  • adding an easy way to obtain arguments' SVals from StackFrameCtx

Since they are independent changes, please submit them as separate patches. This simplifies the job of the reviewers and anyone who will ever look at this patch in commit history or on phabricator. Also, this ensures that each change has sufficient test coverage. The LLVM Dev policy has a great explanation of the reasoning behind this: http://llvm.org/docs/DeveloperPolicy.html#incremental-development.

How do you plan on testing these changes? The main 2 methods are unit tests and checker regression tests. Since no checker uses these maybe we should only commit them once such checker is added...

I've only started looking at the first change and would like to understand the motivation behind it a bit more.

include/clang/StaticAnalyzer/Core/Checker.h
325

LocationContext can be obtained by calling CallEvent::getLocationContext(). I do not think that adding another parameter here buys us much. Am I missing something?

333

What is the scenario in which you need the context here? The idea is that the checker would be interested in region changes if it is already tracking information in the state. For that check, the information in the state is sufficient. What is your scenario?

Also, For any checker API change, we need to update the CheckerDocumentation.cpp.

Hi again!

Thanks for review! I'll upload updated version of this patch today in the evening/tomorrow. As Anna suggested I'll split it into two parts - one regarding extraction of argument SVals for StackFrameCtx and another one adding LocationContext to check::RegionChanges interface. I have commented inline on why I think this change is needed.

Cheers!

include/clang/StaticAnalyzer/Core/Checker.h
325

How about the situation when this callback is triggered by something other than a call, like variable assignment? I've tried using that location context and had lots of segfaults as in such cases it appeared to be null. Do you have some info that it should be non-null in such a case?

333

Well I've added it to be consistent with checkRegionChanges, but AFAIK this callback is no longer necessary and there was a discussion about getting rid of it altogether. Maybe it's a good moment ot purge it?

include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
231

Will do!

741

Yeah, as Anna suggested I will split this change and the addition of LocationContext in check::RegionChanges and we should probably continue this discussion there

NoQ added inline comments.Nov 15 2016, 4:56 AM
include/clang/StaticAnalyzer/Core/Checker.h
325

CallEvent* is optional here - it's there only for invalidations through calls.

333

Environment, which is a significant portion of the state, is essentially unaccessible without a location context.

Call stack is also an important bit of information to any checker that does something special to support/exploit the inlining IPA - there are many checkers that scan the call stack, but so far none of them needed to subscribe to checkRegionChanges; their possible use case may look like "we want an update only if a certain condition was met within the current stack frame".

For the recursion checker, i think, the point is "if current frame is spoiled, we no longer want updates" (which should probably be fixed in the checker patch: even though the callback is broken, it'd take one less action to fix it if we decide to).

zaks.anna added inline comments.Nov 15 2016, 2:16 PM
include/clang/StaticAnalyzer/Core/Checker.h
325

Ok, makes sense. Have you looked into providing a checker context there? How much more difficult would that be? If that is too difficult, adding LocationContext is good as well.

If Call is optional and LocationContext is not, should the Call parameter be last.

333

I don't recall where that discussion has ended. If the callback is not used, I'd be fine with removing it. (That would need to be a separate patch.)

NoQ added inline comments.Nov 17 2016, 12:15 AM
include/clang/StaticAnalyzer/Core/Checker.h
325

If we add a CheckerContext, then we may end up calling callbacks that split states within callbacks that split states, and that'd be quite a mess to support.

Right now a checker may trigger checkRegionChanges() within its callback by manipulating the Store, which already leads to callbacks within callbacks, but that's bearable as long as you can't add transitions within the inner callbacks.

zaks.anna added inline comments.Nov 17 2016, 11:31 PM
include/clang/StaticAnalyzer/Core/Checker.h
325

This argument by itself does not seem to be preventing us from providing CheckerContext. For example, we could disallow splitting states (ex: by setting some flag within the CheckerContext) but still provide most of the convenience APIs.

The advantage of providing CheckerContext is that it is a class that provides access to different analyzer APIs that the checker writer might want to access. It is also familiar and somewhat expected as it is available in most other cases. It might be difficult to pipe enough information to construct it... I suspect that is the reason we do not provide it in this case.

I am OK with the patch as is but it would be good to explore if we could extend this API by providing the full CheckerContext.

NoQ added inline comments.Nov 18 2016, 9:05 AM
include/clang/StaticAnalyzer/Core/Checker.h
325

Hmm, with this kind of plan we should probably move all transition functionality into a sub-class of CheckerContext(?) So that it was obvious from the signature that some of those are restricted, and some are full-featured.

This definitely sounds like a big task, useful though, maybe a separate patch over all callbacks might be a good idea.

NoQ commandeered this revision.Nov 29 2016, 11:59 PM
NoQ added a reviewer: k-wisniewski.

Seems to become outdated with D27090.

NoQ abandoned this revision.Nov 29 2016, 11:59 PM