"David Mosberger-Tang" <[EMAIL PROTECTED]> writes: > Samuel, > > You're missing the point of the check-implicit-pointer-functions > script. Its purposes is not to "grep for warnings" but instead to > look for pairs of warnings that are *guaranteed* to cause crashes on > 64-bit machines. gcc -Wall normally spits out tons of spurious > warnings for 64-bit dirty code, but most of those warnings are just > noise. The problem with gcc-4.0 warnings is that you can't > distinguish between harmless implicit function declarations and ones > that need to be flagged. Example: > > $ cat t.c > char * > foo (char *str) > { > return strdup (str); > } > > enum e_t { a, b }; > > enum e_t > bar (char *str) > { > return strlen (str); > } > $ gcc-3.3 -c -g -O -Wall t.c > t.c: In function `foo': > t.c:4: warning: implicit declaration of function `strdup' > t.c:4: warning: return makes pointer from integer without a cast
(all asm is from amd64) 0000000000400500 <foo>: 400500: 48 83 ec 08 sub $0x8,%rsp 400504: 31 c0 xor %eax,%eax 400506: e8 d5 fe ff ff callq 4003e0 <[EMAIL PROTECTED]> 40050b: 48 83 c4 08 add $0x8,%rsp 40050f: 48 98 cltq 400511: c3 retq The return value of strdup is passed back unaltered. No crash. > t.c: In function `bar': > t.c:12: warning: implicit declaration of function `strlen' > $ gcc-4.0 -c -g -O -Wall t.c > t.c: In function 'foo': > t.c:4: warning: implicit declaration of function 'strdup' > t.c:4: warning: incompatible implicit declaration of built-in function > 'strdup' 00000000004004b0 <foo>: 4004b0: e9 2b ff ff ff jmpq 4003e0 <[EMAIL PROTECTED]> Same thing but gcc detected tail recursion and just jumps into strdup. > t.c: In function 'bar': > t.c:12: warning: implicit declaration of function 'strlen' > t.c:12: warning: incompatible implicit declaration of built-in function > 'strlen' > > As you can see, the gcc-4.0 warnings are inferior because they > provides no way to distinguish the "foo" vs. "bar" case, even though > they are qualitatively different. > > --david They aren't different as both mean data loss if the implicit types would be used as such: int strdup(char *s); vs. char *strdup(const char *s); Conversion between int and pointer loose the upper 32bit of the address. int strlen(char *s); vs. size_t strlen(const char *s); Conversion between 32bit int to 64bit int looses the top 32bit of the size. This usualy goes unnoticed since strings usualy are longer than 2GB. But think about lseek() on files > 2GB. This is just as dangerous. I actualy had to think hard to come up with an example of an implicit function declaration doing the wrong thing on amd64. For an implicit function declaration to fail the binary data passed to the function (or back) would have to differ in format. And the format is mostly just a register. Case one: Custom function returning a double // double myfabs(double x); double foo(double x) { return myfabs(x); } Without prototype: foo.c:2: warning: implicit declaration of function 'myfabs' 0000000000000000 <foo>: 0: 48 83 ec 08 sub $0x8,%rsp 4: b8 01 00 00 00 mov $0x1,%eax 9: e8 00 00 00 00 callq e <foo+0xe> e: f2 0f 2a c0 cvtsi2sd %eax,%xmm0 12: 48 83 c4 08 add $0x8,%rsp 16: c3 retq With prototype: 0000000000000000 <foo>: 0: e9 00 00 00 00 jmpq 5 <foo+0x5> Case two: Overloading an implicit function // int fabs(double x); int foo(double x) { return fabs(x); } Without prototype: foo.c:3: warning: implicit declaration of function 'fabs' foo.c:3: warning: incompatible implicit declaration of built-in function 'fabs' 0000000000000000 <foo>: 0: 66 0f 54 05 00 00 00 andpd 0(%rip),%xmm0 # 8 <foo+0x8> 7: 00 8: f2 0f 2c c0 cvttsd2si %xmm0,%eax c: c3 retq With prototype: foo.c:1: warning: conflicting types for built-in function 'fabs' 0000000000000000 <foo>: 0: e9 00 00 00 00 jmpq 5 <foo+0x5> In both cases the code does the wrong thing without prototype. In the first case the int register will be returned instead of the float register giving a random result. In the second case the overloaded function isn't even called. So the gcc-4.0 warning about built-in function actualy servers a very important function: It warns when gcc does not call the (potentialy) users function. I've seen enough code that define their own fabs, strnlen, .... MfG Goswin PS: Systems that pass arguments on the stack are far more vulnerable to implicit functions. -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]