Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an equivalent to __attribute__((ns_returns_retained)) for a malloc'd pointer?

I'm looking for an annotation something like

-(SomeStruct *) structFromInternals __attribute__((returns_malloced_ptr))
{
    SomeStruct *ret = malloc(sizeof(SomeStruct));
    //do stuff
    return ret;
}

to soothe the clang static analyzer beasts. The only viable attributes link I can find is for GCC, but it doesn't even include ns_returns_retained, which is in an extension, I assume.

EDIT:

as to why this is needed, I have a scenario that I can't repro in a simple case, so it may have to do with a c lib in an Objective-C project... The gist is, I get a static analyzer warning that the malloc in createStruct is leaked:

typedef struct{
    void * data;
    size_t len;
}MyStruct;

void destroyStruct(MyStruct * s)
{
    if (s && s->data) {
        free(s->data);
    }
    if (s) {
        free(s);
    }
}
MyStruct * createStructNoCopy(size_t len, void * data)
{
    MyStruct * retStruct = malloc(sizeof(MyStruct));
    retStruct->len = len;
    retStruct->data = data;
    return retStruct;
}
MyStruct * createStruct(size_t len, void * data)
{
    char * tmpData = malloc(len);
    memcpy(tmpData, data, len);
    return createStructNoCopy(len, tmpData);
}
MyStruct * copyStruct(MyStruct * s)
{
    return createStruct(s->len, s->data);
}
like image 641
Grady Player Avatar asked Apr 29 '13 18:04

Grady Player


1 Answers

The function annotation ownership_returns(malloc) will tell the Clang static analyser that the function returns a pointer that should be passed to free() at some point (or a function with ownership_takes(malloc, ...)). For example:

void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
void __attribute((ownership_takes(malloc, 1))) my_free(void *);
...
void af1() {
    int *p = my_malloc(1);
    return; // expected-warning{{Potential leak of memory pointed to by}}
}
void af2() {
    int *p = my_malloc(1);
    my_free(p);
    return; // no-warning
}

(See the malloc-annotations.c test file for some more examples of their use.)

At the moment, these annotations only take effect when the alpha.unix.MallocWithAnnotations checker is run (which is not run by default). If you're using Xcode, you'll need to add -Xclang -analyzer-checker=alpha.unix.MallocWithAnnotations to your build flags.

like image 136
一二三 Avatar answered Oct 20 '22 15:10

一二三