Bug 59231 - [4.8/4.9 Regression] gcc misses [-Werror=sign-compare] when inside a template
Summary: [4.8/4.9 Regression] gcc misses [-Werror=sign-compare] when inside a template
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.2
: P2 normal
Target Milestone: 4.9.0
Assignee: Jason Merrill
URL:
Keywords: diagnostic
: 59232 (view as bug list)
Depends on: 11856
Blocks: 82521
  Show dependency treegraph
 
Reported: 2013-11-21 12:42 UTC by a_mcgurn
Modified: 2020-01-30 01:42 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-11-21 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description a_mcgurn 2013-11-21 12:42:47 UTC
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
Comment 1 Richard Biener 2013-11-21 13:03:41 UTC
Confirmed.
Comment 2 Richard Biener 2013-11-21 13:05:00 UTC
*** Bug 59232 has been marked as a duplicate of this bug. ***
Comment 3 Jakub Jelinek 2013-12-03 15:15:57 UTC
This has changed in r187542 and from what I can see, the change was completely intentional.
Comment 4 Manuel López-Ibáñez 2013-12-03 16:07:23 UTC
(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).
Comment 5 Jason Merrill 2014-01-24 18:21:45 UTC
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.
Comment 6 Paolo Carlini 2014-01-24 19:36:11 UTC
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 ;)
Comment 7 Jason Merrill 2014-01-27 14:54:10 UTC
(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.
Comment 8 Jason Merrill 2014-02-26 21:28:45 UTC
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
Comment 9 Jason Merrill 2014-02-26 21:33:59 UTC
Fixed for 4.9.