The following code: ----------- //filename #include <iostream> template<class X, class Y> bool equals( X x, Y y ) { return (x == y); } int main() { std::cout << "Hello World!" << std::endl; size_t x = 2; signed int y = 2; if(!equals( x, y )) { std::cout << "Hello World again - x == y !" << std::endl; } return 0; } ----------- This produces for g++-4.8.2: bfs-dl360g7-27$ g++ --std=c++11 -Wall helloWorld.cpp -o helloWorld NO warnings for g++-4.4.7 it correctly warns on the 'signed == unsigned long' as incorrect: bfs-dl360g7-27$ /usr/bin/g++ -Wall helloWorld.cpp -o helloWorld helloWorld.cpp: In function âbool equals(X, Y) [with X = long unsigned int, Y = int]â: helloWorld.cpp:16: instantiated from here helloWorld.cpp:7: warning: comparison between signed and unsigned integer expressions ---- However if comparison is not inside a template say direct comparison: if(x == y) then g++-4.8.2 will pick this up as a warning: bfs-dl360g7-27$ g++ --std=c++11 -Wall -Werror testComparison.cpp -o testComparison testComparison.cpp: In function âint main()â: testComparison.cpp:9:12: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare] if(x == y) so it appears to have difficulty seeing this issue if wrapped in a template/macro. bfs-dl360g7-27$ g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/gcc-4.8.2/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.8.2/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ./configure --prefix=/opt/gcc-4.8.2 --enable-languages=c,c++ --with-mpc=/opt/gcc-4.8.2 --with-mpfr=/opt/gcc-4.8.2 --with-gmp=/opt/gcc-.8.2 --with-cloog=/opt/gcc-4.8.2 --with-isl=/opt/gcc-4.8.2 Thread model: posix gcc version 4.8.2 (GCC) preprocessed file attached - apologies if i've missed anything vital or a bug already raised. rgds
Confirmed.
*** Bug 59232 has been marked as a duplicate of this bug. ***
This has changed in r187542 and from what I can see, the change was completely intentional.
(In reply to Jakub Jelinek from comment #3) > This has changed in r187542 and from what I can see, the change was > completely intentional. Interestingly, the same was done recently in Clang: http://llvm.org/bugs/show_bug.cgi?id=8682 That commit also killed warnings for non-dependant types within templates: unsigned int z; signed int w; template<class X, class Y> bool equals( X x, Y y ) { return (z == w); } (It would be nice to edit the log of that commit to fix the PR number, which should be 11856).
In retrospect, I think that change (which I suggested) was wrong. We don't want to suppress all warnings just because we're in a template; c_inhibit_evaluation_warnings should only be used when we aren't actually generating code for an expression. A better solution for 11856 would be to disable just -Wtype-limits in template instantiations, or even just across the build_x_binary_op if the expression before substitution is type-dependent.
However, what Jason suggested at the time was "ANOTHER job for c_inhibit_evaluation_warning" (emphasis mine). In my mind that was important because I saw a clear consistency rationale in the fix. Before changing / reverting anything here, we should therefore audit all those uses and figure out which ones we want to remove and finally decide which replacement. Frankly, I'm not sure this is 4.9 material (whoever does the job ;)
(In reply to Paolo Carlini from comment #6) > However, what Jason suggested at the time was "ANOTHER job for > c_inhibit_evaluation_warning" (emphasis mine). In my mind that was important > because I saw a clear consistency rationale in the fix. Before changing / > reverting anything here, we should therefore audit all those uses and figure > out which ones we want to remove and finally decide which replacement. > Frankly, I'm not sure this is 4.9 material (whoever does the job ;) Yes, I saw it as a consistency issue. But now I think that was forcing consistency between two importantly different cases: the purpose of c_inhibit_evaluation_warning is to avoid warning about evaluation issues for expressions that are not actually evaluated. But a template instantiation is not an unevaluated context, so it's a different case. Furthermore, the -Wtype-limits warning still makes sense even in unevaluated context, so it shouldn't be conditional on that. I agree that an audit is needed here; we might want to introduce a new counter to indicate dependent context and suppress some warnings within templates. I think this could still go into 4.9 if there's time to take care of it soon.
Author: jason Date: Wed Feb 26 21:28:08 2014 New Revision: 208183 URL: http://gcc.gnu.org/viewcvs?rev=208183&root=gcc&view=rev Log: PR c++/59231 PR c++/11586 PR c++/14710 PR c++/57132 gcc/ * c-common.c (shorten_compare): Don't check c_inhibit_evaluation_warnings. gcc/cp/ * pt.c (struct warning_sentinel): New. (tsubst_copy_and_build): Use it instead of c_inhibit_evaluation_warnings. Added: trunk/gcc/testsuite/g++.dg/warn/Wsign-compare-7.C Modified: trunk/gcc/c-family/ChangeLog trunk/gcc/c-family/c-common.c trunk/gcc/cp/ChangeLog trunk/gcc/cp/pt.c trunk/gcc/cp/typeck.c trunk/gcc/testsuite/g++.dg/cilk-plus/AN/array_test2_tplt.cc trunk/gcc/testsuite/g++.dg/cpp0x/overflow1.C
Fixed for 4.9.