Bug 110933 - Add warnings to detect wrapping happening inside a loop (an infinite loop)
Summary: Add warnings to detect wrapping happening inside a loop (an infinite loop)
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: analyzer (show other bugs)
Version: unknown
: P3 enhancement
Target Milestone: ---
Assignee: David Malcolm
URL:
Keywords: diagnostic
Depends on:
Blocks: new-warning, new_warning
  Show dependency treegraph
 
Reported: 2023-08-07 10:56 UTC by Niklas Hambüchen
Modified: 2023-08-07 15:51 UTC (History)
0 users

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 Niklas Hambüchen 2023-08-07 10:56:59 UTC
GCC currently lacks good compile-time warnings that help find common integer overflow bugs.

For example, the code

    #include <stdint.h>

    void f(uint64_t n)
    {
        for (uint32_t i = 0; i < n; ++i) {
        }
    }

will loop forever if `n` happens to be around 5 billion.

This is a mistake many programmers make (I've had to fix multiple instances of this in common Free Software programs, and similar instances in the Linux kernel).
The bug is not easy to spot because this standard incrementing-loop construct looks "very terminating", and it gets much harder when typedefs, macros, or C++ type templates are involved.

(I would like to file this feature request both for C and C++, but Bugzilla doesn't allow that, so I'm picking C++.)

Existing warnings such as `-Wsign-compare` are of the right spirit, but do not help with e.g. simple unsigned integers.

In 
https://stackoverflow.com/questions/76840686/how-can-i-get-a-warning-when-comparing-unsigned-integers-of-different-size-in-c/

I asked for current ways to find such issues. The best current approaches are a non-trivial clang-query invocation, and closed-source tools such as PVS Studio.

It would be better if GCC itself had better warnings to help with this.

In the above case, we have a binary operator between a wider and a narrower integer type, and implicit (invisible) upcasting (widening) happens.

Having a flag to warn about such implictly-converting binary ops would go a long way, but maybe there's a more general approach to this.

The implementation of such flag should probably consider some common benign special cases, such as comparing with an integer literal that gets upcast (`x > 0` vs `0ul` -- safe since this constant exists in both domains).

It is clear that such warning would likely not be on by default, but it could help tremendously for modernising software projects that e.g. weren't written with a 64-bit mindset.
Comment 1 Niklas Hambüchen 2023-08-07 10:59:17 UTC
A tangentially related issue is bug 24542 which is about another common overflow bug, the pattern "u64 = u32 * u32".

Just linking it here because people interested in solving integer overflow issues may find it relevant.
Comment 2 Richard Biener 2023-08-07 12:08:11 UTC
I think there should be specific warnings for the specific cases, not one that tries to be general.

The example you give might be -Wiv-bound-conversion?
Comment 3 Andrew Pinski 2023-08-07 14:32:05 UTC
Try -Wconversion.

Also there is no overflow here as unsigned is always defined as wrapping.
Comment 4 Andrew Pinski 2023-08-07 15:51:42 UTC
So -Wconversion does not warn in this case as there is the conversion is being promoted rather than a truncation.
That is
i < n
is being done in uint64_t.

> find common integer overflow bugs.
Again in this case there is NO integer overflow. There is only unsigned integer wrapping happening which is well defined C/C++ behavior.
Just the programmer was not expecting them and maybe should be warned about but I always get the feeling this should be a -fanalyzer option as there needs to be some extra static analysis to make sure if the programmer checks for the wrapping we don't warn about it always ...