Unavailable method checker

Jordan Rose jordan_rose at apple.com
Fri Oct 4 18:24:58 PDT 2013


On Oct 3, 2013, at 3:21 , Richard <tarka.t.otter at gmail.com> wrote:

> 
> On 2 Oct 2013, at 03:23, Jordan Rose <jordan_rose at apple.com> wrote:
> 
>> 
>> On Oct 1, 2013, at 9:40 , Jordan Rose <jordan_rose at apple.com> wrote:
>> 
>>> [+cfe-commits, which I didn't really mean to remove]
>>> 
>>> On Sep 27, 2013, at 1:01 , Richard <tarka.t.otter at gmail.com> wrote:
>>> 
>>>> 
>>>> On 25 Sep 2013, at 18:44, Jordan Rose <jordan_rose at apple.com> wrote:
>>>> 
>>>> Yes, the SVal was an UnknownVal, that was it. I have fixed the dtor.cpp test by forcing a transition for StNonNull at the end of checkPreStmt with:
>>>> 
>>>>   C.addTransition(StNonNull, this);
>>>> 
>>>> Unfortunately the other test failure remains, method-call-path-notes.cpp. This one is a bit trickier, checkPreCall is now being called and the null state is triggering a bug report. The problem is the generateSink() method in emitBadCall() is returning null, so the bug is never actually reported.
>>>> 
>>>> I guess the previously generated sink is causing the new sink to not be generated, but I do not know how to work around this. The generated graph is also a bit odd, I have attached it in case it is any help. Any suggestions here?
>>> 
>>> Hm, I wonder if this is from the missing return at the end of the null check clause in checkPreStmt. Transitioning to StNonNull when we know the value is null is just wrong. I'll commit that back soon, but meanwhile can you try it locally?
>>> 
>>> (That probably also means you don't have to add the ", this" to the final addTransition there.)
>> 
>> Committed in r191805.
>> 
>> Jordan
>> 
> 
> Unfortunately this does not fix either issue, as in both cases we have an UnknownVal for the SVal, so we never hit the early return. 
> 
> I am wondering if C++ member expressions should have special handling in the CallAndMessageChecker. Is it possible for a C++ member function to be null? I'm afraid my knowledge of C++ is insufficient to offer anything more constructive at this point, but doing an early return from CallAndMessageChecker::checkPreStmt for CXXMemberCallExpr fixes the bug, and does not cause any new ones to materialise.

Member pointers can most certainly be null, but we don't handle it yet:

struct Foo {
	int bar();
};

void test(Foo *obj) {
	int (Foo::*mp)() = 0;
	(obj->*mp)(); // should warn but don't
}

Instead, let's think about why that would fix the problem. We shouldn't be generating a sink node anymore in the non-null case, and either we changed the state or we didn't. With the change to CheckerContext::addTransition, though, checkPreStmt generates a new node tagged with the checker, but with the same state as before. Then when we get to checkPreCall, we try to do the same thing again, and there we cache out.

I think what this means is that rather than completely removing the check in CheckerContext::addTransition, we should either check if the predecessor node is tagged, or just document that if nothing changed, you don't get a new node unless you explicitly pass the checker as a tag. How many places would need to change if you had to do that?

Jordan

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131004/6aed22a4/attachment.html>


More information about the cfe-commits mailing list