------- Comment #4 from thutt at vmware dot com 2008-12-23 15:40 ------- /* I concur with Ulrich, but three years on, using gcc 4.1.2.
Although a parameter which is marked with the 'nonnull' attribute is demonstrably nonnull, and although the compiler recognizes it is specifically NULL, no warning is emitted. And, in fact, the compiler can end up generating bad code. Using built-in specs. Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man \ --infodir=/usr/share/info --enable-shared --enable-threads=posix \ --enable-checking=release --with-system-zlib --enable-__cxa_atexit \ --disable-libunwind-exceptions --enable-libgcj-multifile \ --enable-languages=c,c++,objc,obj-c++,java,fortran,ada \ --enable-java-awt=gtk --disable-dssi --enable-plugin \ --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre \ --with-cpu=generic --host=x86_64-redhat-linux Thread model: posix gcc version 4.1.2 20071124 (Red Hat 4.1.2-42) gcc -c -o nonnull.o -O3 -Wall nonnull.c nonnull.c: In function f1: nonnull.c:52: warning: null argument where non-null required (argument 1) nonnull.c:52: warning: null argument where non-null required (argument 2) objdump --disassemble --reloc nonnull.o nonnull.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <f1>: 0: f3 c3 repz retq 2: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) If '-Wall' is not provided, the compiler does not even warn about the NULL arguments. It hardly matters if the compiler warns or not, the code that is generated for 'f1()' is simply bad code. But, when no warning is provided by the compiler, the code is egregiously bad -- anyone wondering why their program doesn't work may disassemble the object module and see that nothing was emitted. 0000000000000010 <f0>: 10: ba 00 04 00 00 mov $0x400,%edx ; length = 1024 15: 31 f6 xor %esi,%esi ; second arg = NULL 17: bf 00 00 00 00 mov $0x0,%edi ; first arg = buf 1c: 48 c7 05 00 00 00 00 movq $0x0,0(%rip) ; a = buf 23: 00 00 00 00 27: 48 c7 05 00 00 00 00 movq $0x0,0(%rip) ; b = NULL 2e: 00 00 00 00 32: e9 00 00 00 00 jmpq memcpy In this function, the compiler has automatically inlined 'copy_block()', and obviously determined that the second parameter is NULL, as can be seen from addresses 15 & 27 -- but still no warning is presented. */ #include <stdlib.h> #include <string.h> extern void *a; extern void *b; static void __attribute__((nonnull(1, 2))) copy_block(void *dest, void *src) { memcpy(dest, src, 1024); } void f0(void) { static char buf[100]; a = buf; b = NULL; copy_block(a, b); } void f1(void) { copy_block(NULL, NULL); } -- thutt at vmware dot com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |thutt at vmware dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17308