Bug 66622 - -Wsign-conversion does not take advantage of data flow analysis
Summary: -Wsign-conversion does not take advantage of data flow analysis
Status: RESOLVED DUPLICATE of bug 38470
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 5.1.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2015-06-22 08:29 UTC by John Marshall
Modified: 2015-06-22 10:41 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John Marshall 2015-06-22 08:29:04 UTC
With GCC 5.1 built from gcc-5.1.0.tar.bz2 on OS X:

Target: x86_64-apple-darwin13.4.0
Configured with: ../gcc-5.1.0/configure --prefix=... --enable-languages=c,c++,fortran
Thread model: posix
gcc version 5.1.0 (GCC) 

The following C program compiled with -Wsign-conversion produces a warning:

unsigned foo(int i) {
  if (i < 0) return 0;
  else return i;
}

$ gcc-5.1 -c -Wsign-conversion valueconv.c 
valueconv.c: In function ‘foo’:
valueconv.c:3:15: warning: conversion to ‘unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]
   else return i;

However if the compiler took advantage of the fact that i>=0 within the else, it would realise the warning was a false positive.
Comment 1 Mikhail Maltsev 2015-06-22 10:28:00 UTC
That is possible to implement, but not easy. The compiler transforms code in such a way that lots of information is lost and it's hard to tell which code was written by user, and which was generated by the compiler. Very few warnings are actually emitted at the stage when data flow (use-def chains and value ranges) is known (for example -Wmaybe-uninitialized, but it has rather frequent false positives: https://gcc.gnu.org/bugzilla/buglist.cgi?quicksearch=Wmaybe-uninitialized).

In your case the program will look like this at very early stage:

unsigned foo(int i)
{
  unsigned result;  
  if (i < 0)
    goto bb1;
  else
    goto bb2;
bb1:
  result = 0;
  return result;
bb2:
  result = (unsigned)i;
  return result;
}

Later it will be impossible to say, whether the conversion was introduced explicitly by user, or by the compiler.

Clang also gives false positive. EDG does not warn for such conversions (even unconditional).
Comment 2 Manuel López-Ibáñez 2015-06-22 10:41:38 UTC
It would be great if someone tried to implement this someday, it doesn't seem trivial though.

(In reply to Mikhail Maltsev from comment #1)
> Clang also gives false positive. EDG does not warn for such conversions
> (even unconditional).

As far as I can tell, if the warning is given in the FE by using some kind of limited VRP (which is what Clang does), the number of false positives can only decrease, since the worst that can happen is that the analysis is not powerful enough. The main objection to this has been the extra compilation time that this analysis may require just for a warning (with GCC being already too slow).

Implementing it in the middle-end seems to me worse, since, as you point out, then you may increase the number of false positives and strange things may happen once other optimizations transform the code (also, optimization may hide valid warnings).

A third proposal that has been floated around is to somehow mark the statement with the warning but not emit it until after optimization. If the warning survives after the middle-end analysis, then it will be given. This approach seems even more complex to me.

*** This bug has been marked as a duplicate of bug 38470 ***