Created attachment 24188 [details] minimized test case Hi. My first bug report to gcc :) $ gcc-4.6 -v Using built-in specs. COLLECT_GCC=gcc-4.6 COLLECT_LTO_WRAPPER=/usr/lib/gcc/i486-linux-gnu/4.6.1/lto-wrapper Target: i486-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.0-6' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-multiarch --with-multiarch-defaults=i386-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --enable-targets=all --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.6.1 20110428 (prerelease) (Debian 4.6.0-6) linux (2.6.38) kernel fails to compile when using gcc 4.6. It fails on binfmt_misc.o compilation. Minimized test case attached (from 780703 bytes, down to 471 bytes, thanks to delta) gcc 4.5.3 works without problem. gcc 4.6.1 gives: $ gcc-4.6 -O2 -c binfmt_misc_ultramini.i binfmt_misc_ultramini.i: In function ‘p.part.0’: binfmt_misc_ultramini.i:8:14: error: call to ‘c_overflow’ declared with attribute error: c() buffer size is not provably correct $ Regression dissapear when i use -O3 or -finline-functions optimization. Also problem disapears when i subtelly change minimized test case. Thus it is problem with inliner. Regards, Witek
In original source a c function have this signature: static inline __attribute__((always_inline)) unsigned long __attribute__((warn_unused_result)) copy_from_user(void *to, const void *from, unsigned long n) but putting back inline or __attribute__((always_inline)) (or both) do not change anything.
The testcase is quite questionable, and the reason it "fails" with gcc 4.6 is partial inlining. Related to PR46639, again being able to run VRP through the body of the partially inlined fn before handling the p.part.0 VRP would fix this. In *.fnsplit p is: p (unsigned int n) { int D.2699; <bb 2>: if (n_2(D) == 0) goto <bb 5>; else goto <bb 3>; <bb 3>: if (n_2(D) > 3) goto <bb 5>; else goto <bb 4>; <bb 4>: D.2699_9 = p.part.0 (n_2(D)); <bb 5>: # D.2699_1 = PHI <0(2), -22(3), D.2699_9(4)> return D.2699_1; } so if VRP would figure out that p.part.0's first argument has range [1, 3], it could optimize away the test in p.part.0.
In my case it only happens if I have two independent calls with different arguments. I do not understand some aspects, but removing some semingly unrelated things or adding some dummy variable write, make bug disapear. It shouldn't matter, but maybe VRP information is somehow cached for each block, and this caching do not takes into accout some additional informations? It looks very similar to PR46639 - in original test case I even had program with structure somehow similar to one from PR46639 (assigning a pointer function to the static global variable), but after minimizing it further I removed it and failure still occurs. As of figuring out that at <bb 4> a n_2(D) is in range [1, 3] isn't hard. It can be done both in forward as well a backward manner. (but of course VRP works by propgating forward, but does it consider separetly all data paths?) I know it isn't bug, but is regression and gcc isn't doing properly VRP or inlineing somewhere probably. I reported it only because kernel failed to compile :) And AFAIK linux kernel uses extensively static checks for things like memset, memcpy, copy_from_user, etc., to make sure all calls call them with legth/count/size not bigger than actual buffer size to which they are writing or reading. I of course can compile linux kernel by unseting proper CONFIG_* in kernel configuration. It is also quite important as it could remove significant amount of dead code after partial inlineing.
Dup of PR46639 *** This bug has been marked as a duplicate of bug 46639 ***