Bug 37591 - suppress "signed and unsigned" warnings when signed value known to be positive
Summary: suppress "signed and unsigned" warnings when signed value known to be positive
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.3.2
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2008-09-19 18:12 UTC by Zack Weinberg
Modified: 2020-11-06 22:10 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-09-20 09:10:32


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zack Weinberg 2008-09-19 18:12:32 UTC
In a case such as this, GCC ought to be able to prove that the signed variable is positive and therefore suppress "signed and unsigned" warnings.  I see this in both C and C++.

#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))

unsigned int
constrain(unsigned int index, unsigned int offset, unsigned int limit)
{
  int adj = index - offset;
  adj = MAX(adj, 0);
  return MIN(adj, limit); /* { dg-bogus "signed and unsigned" } */
}
Comment 1 Andrew Pinski 2008-09-19 20:55:28 UTC
I think this needs to delay the warning until VRP time really but I don't see how that can be done really.
Also the front-end does known that adj will only be positive, the middle-end only knows during VRP really.
Comment 2 Zack Weinberg 2008-09-19 21:28:30 UTC
I'd be fine with it being like uninitialized value warnings.  The false positives here are *really* annoying.
Comment 3 Richard Biener 2008-09-20 09:10:32 UTC
This is the usual trade-off of doing warnings from the frontends...
Comment 4 Manuel López-Ibáñez 2008-09-22 13:28:20 UTC
I don't understand why this is not closed as wontfix. These warnings are coming from the front-end. 

Unless we do one of the following:

a) some CCP and VRP in the FE, or
b) move the warnings to the middle-end,

this cannot be fixed. And the consensus seems to be that we do not want to do either of them. And from the many problems we see with Wuninitialized, we already know that moving the warnings to the middle-end causes a lot of problems. Also, VRP is only enabled at -O2. And it does not work with sets, only ranges, so the following will still not work:

adj = (flag) ? 0 : 2;
return MIN(adj, limit);

(I am sure that we have already, probably closed, a PR about this).
Comment 5 Zack Weinberg 2008-09-22 15:46:07 UTC
I'm not monitoring consensus of developers anymore, but I think we *should* either move these warnings to the middle end or do some CCP/VRP in the front ends.  The -Wuninitialized warnings are a lot less trouble than the signed/unsigned warnings, right now.
Comment 6 Manuel López-Ibáñez 2008-09-22 16:43:25 UTC
Then, try to raise the issue in GCC and outline a clear plan. Otherwise, I assure you this is going to stay as-is for the next 5-10 years because nobody has a clear idea on how to tackle this in a way that pleases a majority. Also, because it has an easy workaround: use a casting to unsigned.

Some starting points:

* Moving the warning to the middle-end is not going to avoid warning in this testcase unless VRP is enabled. For -O0 and -O1, we will keep warning.

* Moving the warning to the middle-end means that we will warn/not warn depending on the ordering of passes, missed optimisations, etc.

* Clang people claim that they can do a simple CCP pass very efficiently in the FE. Perhaps we could do the same. However, we are currently moving optimizations (such as folding) to later stages. In any case, VRP in the front-end is what would be needed for this testcase. Is that even possible? Can be done efficiently?

The same issues apply to many warnings: -Wconversion, -Wuninitialized, -Wtype-limits. 

As Richard said: This is the usual trade-off of doing warnings from the frontends versus from the middle-end. One gives consistency and speed but frequent false positives, and the other gives more precision at the cost of consistent results and more compilation time.
Comment 7 Daniel Marjamäki 2015-07-06 08:59:18 UTC
+1

This is very annoying.

My code is:

unsigned int dostuff();
void f(int x) {
  if (x >= 0 && x < dostuff()) {}
}

This kind of false positive is indirectly a security problem. People routinely hide these false positives using casts or changed variable types etc. and that cause bugs and hides other real warnings.

I'd vote for either removing this warning or fixing it.
Comment 8 Manuel López-Ibáñez 2015-07-06 12:31:43 UTC
> I'd vote for either removing this warning or fixing it.

You can use the corresponding -Wno-* option to remove it.

There's no much point in voting on this or other bugs: What is needed is someone brave enough to tackle the problem and figure out how to solve it in a way that is accepted by the maintainers. https://gcc.gnu.org/wiki/GettingStarted#Basics:_Contributing_to_GCC_in_10_easy_steps

Comment #6 is as relevant today as it was 6 years ago. But perhaps simple cases can be detected without any CCP or VRP in the FE. Someone needs to figure it out.
Comment 9 Eric Gallager 2018-02-20 10:38:29 UTC
I think this is related to bug 38470
Comment 10 Eric Gallager 2019-09-23 05:03:04 UTC
(In reply to Eric Gallager from comment #9)
> I think this is related to bug 38470

Possibly a dup thereof? Or vice versa?