[cfe-dev] [Patch] Generate a warning if a message is sent to a nil receiver with return type larger than void* (PR 2718)

Ted Kremenek kremenek at apple.com
Wed Apr 8 10:48:45 PDT 2009


On Apr 8, 2009, at 1:43 AM, Nikita Zhuk wrote:

>
> On 8.4.2009, at 4.42, Ted Kremenek wrote:
>
>> Hi Nikita,
>>
>> This looks great.  Just to confirm, I think the particular  
>> reference to the Apple documentation is the following:
>>
>> http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/universal_binary_tips.html#//apple_ref/doc/uid/TP40002217-CH239-CJBJABFC
>
> Yes, that's the correct one.
>
> I have a question related to the nil receiver checks. Would it be  
> possible to take the nil receiver assumption (ObjC messages with  
> size of return value <= sizeof(void*) sent to nil always return  
> zero) into account in GRExprEngine, so that the number of false  
> positives could be reduced even further? For example, the following  
> cases generate the nil receiver warning, although the conditions of  
> 'if', 'for' and 'while' statements are always false when the 'obj'  
> is nil (because any message sent to nil returns zero).
>
> for(int i = 0; i < [obj intM]; i++)
> {
> 	long long j = [obj longlongM]; // no-warning  (currently generates  
> the 'nil receiver' warning)
> }
>
> while([obj intM] != 0)
> {
> 	long long j = [obj longlongM]; // no-warning  (currently generates  
> the 'nil receiver' warning)
> }
>
> if([obj intM] != 0)
> {
> 	long long j = [obj longlongM]; // no-warning  (currently generates  
> the 'nil receiver' warning)
> }

Hi Nikita,

I see; [obj intM] should evaluate to 0 if obj is nil.  Sure that would  
be easy to do!

Incidentally, this example touches on same dangerous territory as far  
as reasoning about sending messages to nil, as some of these semantics  
are architecture specific and could change with the whim of any  
updates to the runtime.

As you know, for portability the only thing we can assume is (from the  
referenced doc):

"The Objective-C runtime assumes that the return value of a message  
sent to a nil object is nil, as long as the message returns an object  
or any integer scalar of size less than or equal to sizeof(void*)."

While this seems pretty clear for 'int', pointers, etc., long long  
doesn't fall into that category.  In fact that's only kosher on Intel  
macs, and the documentation even says that is undefined for PowerPC.   
I'm also not certain what the results would be for ARM, but I imagine  
that the result would be undefined as well.  This means this code will  
break when used to build an iPhone app.

I think there are two strategies we can take here.  We either issue  
target-specific warnings or target-independent warnings.  Target- 
independent warnings would flag cases that are potentially non- 
portable.  I realize that you weren't arguing that the analyzer  
specially handle the [ob longlongM] case, but I thought I would bring  
these issues up while we are here.

Ted



More information about the cfe-dev mailing list