Hi. I'm seeing that under particular conditions I can pass a wrong type into a function, and no warning results. I'm attaching a minimized test case to show this. There are two files: bugreport.c and bugreport.h. The .c includes the .h. The issue only happens when the .h file is placed into /usr/include, and included using <> instead of "".
bugreport.c has this snippet:
typedef ... sss_t;
int fff( sss_t* ctx, ... )
sss_t* sss = NULL;
So fff() expects a sss_t* as its first argument, but we're giving it a sss_t** instead. This should generate a warning. However:
dima@shorty:/tmp$ gcc-4.9 -Wall -Wextra -c -o/dev/null bugreport.c
So gcc thinks this is fine. Tweaking the test case even a little bit makes the warning come back. For instance, including the header in the local directory, instead of in /usr/include makes it work, as does simply putting the header the contents into the .c and including nothing. Removing the F() call makes it work. Changing the whitespace in the F() call makes it work.
I'm using gcc 4.9.1 as shipped on Debian/sid:
dima@shorty:/tmp$ dpkg -l gcc-4.9
ii gcc-4.9 4.9.1-1
dima@shorty:/tmp$ gcc-4.9 -v
Using built-in specs.
Configured with: ../src/configure -v --with-pkgversion='Debian 4.9.1-1' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --with-arch-32=i586 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.9.1 (Debian 4.9.1-1)
Created attachment 33451 [details]
The source to show the issue
Created attachment 33452 [details]
and the header
I think I fixed this in r214874. Can you try to update your 4.9 gcc?
Hi. Thank you for looking at this. I'm not set up to make bleeding-edge gcc builds, so let me wait until Debian catches up, and I'll report back. Currently they're on r214759 (not what the bug report mentions, but affected too), and they update relatively often. Thanks again.
I cherry-picked the commit you mentioned, rebuilt gcc, and the bug was not resolved. Just in case I did something wrong in that process, I waited for Debian to update their package. This just happened, and I updated. I'm now using gcc4.9 version 4.9.1-13 from Debian/unstable. The Debian changelog says this is using r215008: http://metadata.ftp-master.debian.org/changelogs//main/g/gcc-4.9/gcc-4.9_4.9.1-13_changelog
As before, the bug is unresolved.
I've tried this again, and I still get the expected warning.
Hi. Thank you once again for replying, Marek.
I just looked into this a bit more deeply, and it appears that this is some sort of ccache artifact. Running without ccache I see the warning with all versions of gcc that I have tried. With ccache, the warning is missing for all gcc-4.9 and gcc-4.8 that I have, but it IS there with gcc-4.4.
So this sounds like a bug in ccache and not gcc. Sorry for the false alarm and thank you very much for looking.
Ah, ccache, that settles it then. NP, you're welcome.
For the record, here's the ccache bug I just filed: https://bugzilla.samba.org/show_bug.cgi?id=10819
I filed this bug against ccache, and its maintainer had some insight and thinks that this is a gcc issue after all. I'm reopening this bug here with the salient portion of the comment from the ccache maintainer copied below. Thanks.
I would say that this is not a ccache bug. For ccache to work as expected in
its default operation mode, the compiler must be able to compile its own
preprocessed source code with the same result as compiling without the
compiler [OPTIONS] -E source.c -o source.i
compiler [OPTIONS] -c source.i -o source.o
needs to give the same result as
compiler [OPTIONS] -c source.c -o source.o
GCC doesn't do that for your test case:
% gcc-4.9 -Wall -Wextra -E bugreport.c -o bugreport.i
% gcc-4.9 -Wall -Wextra -c bugreport.i -o /dev/null
% gcc-4.9 -Wall -Wextra -c bugreport.c -o /dev/null
bugreport.c: In function ‘fn1’:
bugreport.c:14:5: warning: passing argument 1 of ‘fff’ from incompatible
bugreport.c:6:5: note: expected ‘struct sss_t *’ but argument is of type
‘struct sss_t **’
int fff( sss_t* ctx, int a, int b);
bugreport.c:15:1: warning: control reaches end of non-void function
Digging a bit deeper, the behavior difference comes from this part of the
% tail -n 11 bugreport.i
sss_t* sss = ((void *)0);
# 12 "bugreport.c" 3 4
, 0 )
The flag "3" after '# 12 "bugreport.c"' indicates that the following text comes
from a system header, which doesn't look right. (If bugreport.h is found
locally instead of in /usr/include, then the "3" flag disappears.) Sounds like
a GCC bug to me.
Dup of PR60100.
*** This bug has been marked as a duplicate of bug 60100 ***