zaks.anna added inline comments.

================
Comment at: lib/StaticAnalyzer/Checkers/OStreamFormatChecker.cpp:513
+
+bool OStreamFormatChecker::evalCall(const CallExpr *CE,
+                                    CheckerContext &C) const {
----------------
gamesh411 wrote:
> NoQ wrote:
> > One of the practical differences between `checkPostCall` and `evalCall` is 
> > that in the latter you have full control over the function execution, 
> > including invalidations that the call causes. Your code not only sets the 
> > return value, but also removes invalidations that normally happen. Like, 
> > normally when an unknown function is called, it is either inlined and 
> > therefore modeled directly, or destroys all information about any global 
> > variables or heap memory that it might have touched. By implementing 
> > `evalCall`, you are saying that the only effect of calling `operator<<()` 
> > on a `basic_ostream` is returning the first argument lvalue, and nothing 
> > else happens; inlining is suppressed, invalidation is suppressed.
> > 
> > I'm not sure if it's a good thing. On one hand, this is not entirely true, 
> > because the operator changes the internal state of the stream and maybe of 
> > some global stuff inside the standard library. On the other hand, it is 
> > unlikely to matter in practice, as far as i can see.
> > 
> > Would it undermine any of your efforts here if you add a manual 
> > invalidation of the stream object and of the `GlobalSystemSpaceRegion` 
> > memory space (you could construct a temporary `CallEvent` and call one of 
> > its methods if it turns out to be easier)?
> > 
> > I'm not exactly in favor of turning this into `checkPostCall()` because 
> > binding expressions in that callback may cause hard-to-notice conflicts 
> > across multiple checkers. Some checkers may even take the old value before 
> > it's replaced. For `evalCall()` we at least have an assert.
> > 
> > If you intend to keep the return value as the only effect, there's option 
> > of making a synthesized body in our body farm, which is even better at 
> > avoiding inter-checker conflicts. Body farms were created for that specific 
> > purpose, even though they also have their drawbacks (sometimes `evalCall` 
> > is more flexible than anything we could synthesize, eg. D20811).
> > 
> > If you have considered all the alternative options mentioned above and 
> > rejected them, could you add a comment explaining why? :)
> I am not familiar with the BodyFarm  approach, however I tried something 
> along the lines of:
> auto CEvt = 
> ResultEqualsFirstParam->getStateManager().getCallEventManager().getSimpleCall(CE,
>  S, C.getLocationContext());
> ProgramStateRef StreamStateInvalidated = 
> CEvt->invalidateRegions(C.blockCount());
> 
> It however broke test2 (where the state is set to hex formatting, then,  back 
> to dec). Any tips why resetting regions could cause problems?
> 
I agree that we should not use evalCall(), especially, in an opt-in checker, as 
it can introduce subtle/hard to debug issues. As was mentioned, if a checker 
implements evalCall(), the usual evaluation by the analyzer core does not 
occur, which could lead to various unpredictable results. 


https://reviews.llvm.org/D27918



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

Reply via email to