The MallocChecker does not currently detect freeing of function pointers.
Example code.
void (*fnptr)(int); void freeIndirectFunctionPtr() { void *p = (void*)fnptr; free(p); // expected-warning {{Argument to free() points to a function pointer}} }
Differential D31650
[Analyzer] Detect when function pointer is freed AndersRonnholm on Apr 4 2017, 12:42 AM. Authored by
Details The MallocChecker does not currently detect freeing of function pointers. Example code. void (*fnptr)(int); void freeIndirectFunctionPtr() { void *p = (void*)fnptr; free(p); // expected-warning {{Argument to free() points to a function pointer}} }
Diff Detail
Event TimelineComment Actions Hello, thanks for the patch! Because we already warn on freeing concrete function pointers, eg. void foo() { free(&foo); } this is a useful addition. Is freeing function pointers always undefined? I wonder what happens if we take some JIT-enabled javascript engine, maybe with some on-stack replacement of theirs, it may malloc() a memory and use it as a function, and then eventually it'd need to free it by design. However, because we're analyzing a small part of the program, we may fail to see in the analyzer that the symbolic pointer originally comes from malloc(). Would such rare but important users be able to avoid/suppress the warning?
Comment Actions I guess not.. however I don't personally see why it would be useful to allocate function pointers with malloc.
Maybe when writing JIT there is some usecase, I don't know. The code could be rewritten like: void *malloc(unsigned long); void free(void*); typedef void (*fnptr)(int); void allocatedFunctionPointer() { void *p = malloc(sizeof(fnptr)); fnptr p2 = (fnptr)p; free(p); } no warning is written about this code. Comment Actions
sorry ... I guess that should be something like "void *p = malloc(100);" Comment Actions Looks good, thanks! Did you evaluate this on a large codebase - were warnings plentiful and were there any false positives known? I'd like to summon Anna here for a little bit because that's a new check that is enabled by default, so it's always a bit of a historical moment:
|