* Re: Question about -Wstrict-overflow=2
2021-03-07 14:04 ` Alexander Motzkau
@ 2021-03-07 14:56 ` Andrew Haley
2021-03-08 16:43 ` Segher Boessenkool
2021-03-07 15:31 ` Ian Lance Taylor
2021-03-08 21:05 ` Martin Sebor
2 siblings, 1 reply; 11+ messages in thread
From: Andrew Haley @ 2021-03-07 14:56 UTC (permalink / raw)
To: gcc-help
On 3/7/21 2:04 PM, Alexander Motzkau via Gcc-help wrote:
> Andrew Haley wrote:
>> -Wstrict-overflow=2 triggers when GCC encounters expressions that
>> reduce to a constant, where that evaluation depends on overflow not
>> occuring. In this case the expression is
>>
>> expbuf + 120 > get_buf()
>
> If this is the case
It is. I've looked.
> I can see the merit of the warning, because that can be reduced to
> 120 > 0, which is a constant. But my problem ist, that I don't see
> where this expression comes from?
Surely you can imagine some kinds of loop transformation that might
result in such an expression.
-fdump-tree-all might help you. It won't tell you everything, because
sometimes expressions are generated during an optimization pass and
deleted before the dump. But it might help you to understand the kinds
of transformation that GCC does.
> The condition in question is
>
> argptr >= endbuf
>
> which can be written as
>
> expbuf + i >= expbuf + 120
>
> which can be reduced to
>
> i >= 120
>
> which is not a constant, and therefore not a cause for this warning.
>
> This could get constant if gcc does some loop unrolling, for the
> first loop this would result in the expression you quoted. But then
> I would have hoped that gcc doesn't warn about constants or dead
> code when unrolling a loop, because they naturally happen then.
GCC warns when it encounters such an expression when optimizing.
GCC does not distinguish between user-written expressions and
internally-generated ones.
> And I can't do anything against it except unrolling manually and
> this would make it less readable.
That's right, you can't.
>> I doubt that it ever was. -Wstrict-overflow=2 is informative, for
>> the programmer. It doesn't suggest that anything is questionable
>> about the program, and in this case it's difficult or impossible to
>> avoid.
>
> If an originally non-constant if-expression is reduced to a constant
> one that is for me something to worry about, where a warning/error
> is appropriate. It means that the following block is always or never
> executed, something the programmer usually didn't intend, otherwise
> he wouldn't have written the if-condition.
>
> And this reduction to a constant is what differentiates
> -Wstrict-overflow=2 from -Wstrict-overflow=3 (according to gcc's
> documentation). For the later I would accept your description as it
> being purely informative.
Sure, but I'm telling you what is.
>> Re upgrading: over time, GCC gets better and better at diagnosing and
>> providing information. This inevitably means that programmers using
>> -Werror with high levels of warnings have to change their programs
>> when a new GCC is used.
>
> I understand and I welcome better analysis and optimization
> techniques. And I changed several parts due to new warnings. But in
> this case I don't see any possibility that wouldn't make the code
> worse except deactivating the warning. Which is sad and normally
> beside the point of a warning.
Not all warnings indicate things that should be changed. We expect
higher levels of warnings to cause false positives, many of which
can't be avoided, which is why such warnings are not included in
-Wall.
--
Andrew Haley (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Question about -Wstrict-overflow=2
2021-03-07 14:56 ` Andrew Haley
@ 2021-03-08 16:43 ` Segher Boessenkool
0 siblings, 0 replies; 11+ messages in thread
From: Segher Boessenkool @ 2021-03-08 16:43 UTC (permalink / raw)
To: Andrew Haley; +Cc: gcc-help
On Sun, Mar 07, 2021 at 02:56:27PM +0000, Andrew Haley via Gcc-help wrote:
> On 3/7/21 2:04 PM, Alexander Motzkau via Gcc-help wrote:
> > Andrew Haley wrote:
> >> Re upgrading: over time, GCC gets better and better at diagnosing and
> >> providing information. This inevitably means that programmers using
> >> -Werror with high levels of warnings have to change their programs
> >> when a new GCC is used.
> >
> > I understand and I welcome better analysis and optimization
> > techniques. And I changed several parts due to new warnings. But in
> > this case I don't see any possibility that wouldn't make the code
> > worse except deactivating the warning. Which is sad and normally
> > beside the point of a warning.
>
> Not all warnings indicate things that should be changed. We expect
> higher levels of warnings to cause false positives, many of which
> can't be avoided, which is why such warnings are not included in
> -Wall.
Yes. If GCC would know something it warns about is an error, it should
report it as an error. But it doesn't know.
Some warnings are for things that GCC knows (or its developers know,
really) are often wrong. Other warnings are for things that aren't so
often wrong, but have a high impact. And some are for problems that are
hard to find.
-Werror ignores all of this, and makes every warning an error. That can
be handy for people who know they will ignore all warnings otherwise,
and it is not a huge deal for warnings that are part of -Wall (because
one of the conditions for being included there is that the problem is
easy to avoid, with a trivial code change). But -Werror is only for
people who think life is too boring and they need some extra challenges,
otherwise.
There is no reason to avoid all warnings. It is easy to avoid all -Wall
warnings, or even -Wall -Wextra (although if you never used that before
it will find a *lot* of questionable constructs in your code), but most
other warnings are not in either of those two categories precisely
because they are *not* easy to avoid.
Segher
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Question about -Wstrict-overflow=2
2021-03-07 14:04 ` Alexander Motzkau
2021-03-07 14:56 ` Andrew Haley
@ 2021-03-07 15:31 ` Ian Lance Taylor
2021-03-08 21:05 ` Martin Sebor
2 siblings, 0 replies; 11+ messages in thread
From: Ian Lance Taylor @ 2021-03-07 15:31 UTC (permalink / raw)
To: Alexander Motzkau; +Cc: gcc-help
On Sun, Mar 7, 2021, 6:05 AM Alexander Motzkau via Gcc-help <
gcc-help@gcc.gnu.org> wrote:
> Andrew Haley wrote:
> > -Wstrict-overflow=2 triggers when GCC encounters expressions that
> > reduce to a constant, where that evaluation depends on overflow not
> > occuring. In this case the expression is
> >
> > expbuf + 120 > get_buf()
>
> If this is the case I can see the merit of the warning, because that can be
> reduced to 120 > 0, which is a constant. But my problem ist, that I don't
> see where this expression comes from? The condition in question is
>
> argptr >= endbuf
>
> which can be written as
>
> expbuf + i >= expbuf + 120
>
> which can be reduced to
>
> i >= 120
>
> which is not a constant, and therefore not a cause for this warning.
>
As you said earlier, GCC turns the loop into one with exactly 120
iterations. That optimization assumes that expbuf + 120 does not overflow;
if it did overflow the loop would not execute exactly 120 times. That is
why you are getting the warning. It's not an error; it's GCC informing you
that it is making as optimization decision based on the assumption that
overflow does not occur.
Ian
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Question about -Wstrict-overflow=2
2021-03-07 14:04 ` Alexander Motzkau
2021-03-07 14:56 ` Andrew Haley
2021-03-07 15:31 ` Ian Lance Taylor
@ 2021-03-08 21:05 ` Martin Sebor
2021-03-08 21:57 ` Alexander Motzkau
2021-03-09 9:09 ` Andrew Haley
2 siblings, 2 replies; 11+ messages in thread
From: Martin Sebor @ 2021-03-08 21:05 UTC (permalink / raw)
To: Alexander Motzkau, gcc-help
On 3/7/21 7:04 AM, Alexander Motzkau via Gcc-help wrote:
> Andrew Haley wrote:
>> -Wstrict-overflow=2 triggers when GCC encounters expressions that
>> reduce to a constant, where that evaluation depends on overflow not
>> occuring. In this case the expression is
>>
>> expbuf + 120 > get_buf()
>
> If this is the case I can see the merit of the warning, because that can be
> reduced to 120 > 0, which is a constant. But my problem ist, that I don't
> see where this expression comes from? The condition in question is
>
> argptr >= endbuf
>
> which can be written as
>
> expbuf + i >= expbuf + 120
>
> which can be reduced to
>
> i >= 120
>
> which is not a constant, and therefore not a cause for this warning.
>
> This could get constant if gcc does some loop unrolling, for the first loop
> this would result in the expression you quoted. But then I would have hoped
> that gcc doesn't warn about constants or dead code when unrolling a loop,
> because they naturally happen then. And I can't do anything against it
> except unrolling manually and this would make it less readable.
>
>> I doubt that it ever was. -Wstrict-overflow=2 is informative, for the
>> programmer. It doesn't suggest that anything is questionable about the
>> program, and in this case it's difficult or impossible to avoid.
>
> If an originally non-constant if-expression is reduced to a constant one
> that is for me something to worry about, where a warning/error is
> appropriate. It means that the following block is always or never executed,
> something the programmer usually didn't intend, otherwise he wouldn't have
> written the if-condition.
>
> And this reduction to a constant is what differentiates -Wstrict-overflow=2
> from -Wstrict-overflow=3 (according to gcc's documentation). For the later
> I would accept your description as it being purely informative.
>
>> Re upgrading: over time, GCC gets better and better at diagnosing and
>> providing information. This inevitably means that programmers using
>> -Werror with high levels of warnings have to change their programs
>> when a new GCC is used.
>
> I understand and I welcome better analysis and optimization techniques.
> And I changed several parts due to new warnings. But in this case I don't
> see any possibility that wouldn't make the code worse except deactivating
> the warning. Which is sad and normally beside the point of a warning.
In the case of flow-dependent warnings there often is a way to rewrite
the code in a way that make it either faster (because it helps GCC see
invariants it can't infer otherwise) or more readable.
I think rewriting the test as an equality would be an improvement:
argptr is incremented by 1 in each iteration so there's no way for
the pointer to be greater than endbuf.
if (argptr == endbuf)
return false;
This avoids the warning and has no change on the emitted code.
(Of course, if the step can be greater than 1 then using equality
wouldn't be appropriate.)
Martin
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Question about -Wstrict-overflow=2
2021-03-08 21:05 ` Martin Sebor
@ 2021-03-08 21:57 ` Alexander Motzkau
2021-03-09 9:09 ` Andrew Haley
1 sibling, 0 replies; 11+ messages in thread
From: Alexander Motzkau @ 2021-03-08 21:57 UTC (permalink / raw)
To: gcc-help
Martin Sebor wrote:
> I think rewriting the test as an equality would be an improvement:
> argptr is incremented by 1 in each iteration so there's no way for
> the pointer to be greater than endbuf.
The example I gave was very simplified. The original function is much more
complex and argptr is advanced by more than 1 in some cases.
But thank you all for your replies. I understand now, where this warning
comes from (I didn't know -fdump-tree-all, that was very interesting):
GCC does loop header duplication, so the condition is duplicated for the
first iteration and that can (and should) be reduced to a constant assuming
pointers don't wrap around (which they shouldn't).
For now I have turned the comparison of pointers into a comparison of
offsets (by subtraction) to silence the warning. But if GCC gets cleverer
I might remove -Wstrict-overflow=2 alltogether.
Thank you very much
Alex
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Question about -Wstrict-overflow=2
2021-03-08 21:05 ` Martin Sebor
2021-03-08 21:57 ` Alexander Motzkau
@ 2021-03-09 9:09 ` Andrew Haley
1 sibling, 0 replies; 11+ messages in thread
From: Andrew Haley @ 2021-03-09 9:09 UTC (permalink / raw)
To: gcc-help
On 3/8/21 9:05 PM, Martin Sebor via Gcc-help wrote:
> I think rewriting the test as an equality would be an improvement:
> argptr is incremented by 1 in each iteration so there's no way for
> the pointer to be greater than endbuf.
>
> if (argptr == endbuf)
> return false;
You can, but it arguably makes the code more fragile and less easy
to reason about. I'm not in favour of tying programs in knots in order
to appease warnings.
--
Andrew Haley (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
^ permalink raw reply [flat|nested] 11+ messages in thread