On Sun, Mar 20, 2016 at 7:15 AM, Corinna Vinschen <[email protected]> wrote: > Eh, what?!? How on earth can gcc assert memptr is always non-NULL? > An application can call posix_memalign(NULL, 4096, 4096) just fine, > can't it? If so, *memptr = res crashes. >
So, it looks like what's happening is that gcc special-cases posix_memalign as a builtin function. See https://github.com/gcc-mirror/gcc/blob/master/gcc/builtins.def#L831 This causes the below warning to be outputted for my testcase: a.cc:9:25: warning: null argument where non-null required (argument 1) [-Wnonnull] posix_memalign(0,1,1); ^ a.cc: In function ‘int posix_memalign(void**, long unsigned int, long unsigned int)’: a.cc:3:3: warning: nonnull argument ‘memptr’ compared to NULL [-Wnonnull-compare] if (memptr) ^~ Testcase: extern "C" posix_memalign(void **memptr, unsigned long, unsigned long) { void *a = 0; if (memptr) *memptr = a; return 0; } int main() { posix_memalign(0,1,1); } (Note that passing -fno-builtin causes the warning to go away, as posix_memalign is no-longer special-cased) In addition, both newlib and glibc appear to assume the memptr arg is nonnull. https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c#l5008 https://sourceware.org/git/?p=newlib-cygwin.git;a=blob;f=newlib/libc/sys/linux/malloc.c#l4938 Hope that makes this more understandable. Thanks, Peter
