Why is there no counterpart to cf_consumed for the Clang static analyzer that marks an argument as being retained?

228 views Asked by At

Say we want to create our own CFRetain and CFRelease functions, called MyRetain and MyRelease. For the latter, we can just write:

void MyRelease(CFTypeRef __attribute__((cf_consumed)) typeRef);
// or
void MyRelease(CFTypeRef CF_RELEASES_ARGUMENT typeRef);

However, for MyRetain it seems we're out of luck. I would have suspected something like this to exist:

void MyRetain(CFTypeRef __attribute__((cf_retained)) typeRef);
// or
void MyRetain(CFTypeRef CF_RETAINS_ARGUMENT typeRef);

Is this simply an omission? Is there maybe an alternative I'm not seeing?

2

There are 2 answers

0
fish2000 On

You most likely want to use __attribute__((cf_returns_retained)), which is often #define’d as CF_RETURNS_RETAINED.

From the relevant lines in the CoreFoundation source:

#ifndef CF_RETURNS_RETAINED
#if __has_feature(attribute_cf_returns_retained)
#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
#else
#define CF_RETURNS_RETAINED
#endif
#endif

… that file, CFBase.h, is worth perusing – it contains many of the more obscure CF-specific #define and typedef definitions.

0
Carl Lindberg On

I think the usual case would be to declare it as:

CF_RETURNS_RETAINED CFTypeRef MyRetain(CFTypeRef typeRef);

since retaining functions usually return the same value. Release-type functions generally return void so they would have to annotate the argument.