https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100477

--- Comment #7 from andysem at mail dot ru ---
(In reply to Martin Sebor from comment #6)
> In C/C++ the size of the largest object is PTRDIFF_MAX - 1 bytes.  This is
> necessary so that the difference between the address of its first byte and
> that just past its last byte fits in ptrdiff_t.

Sure, but memset, as well as other string operations, takes size_t as an
argument and doesn't have this limitation. They must be able to operate on the
full range of size_t worth of bytes. I don't remember neither C nor C++
declaring a narrowing limit on the allowed size_t range wrt. these functions.

And please note that string functions are often used on raw storage that is
obtained through means other than defined by C++ as operations creating
objects. That storage may be larger than the maximum C++ object size.

> A number of GCC warnings
> point out code that breaks this assumption, including allocations in excess
> of the maximum or calls to functions like memset or memcpy that would access
> more than the maximum.   None of these warnings considers the conditions
> that must be true in order for control to reach the problem statement, so if
> the statement hasn't been eliminated from in the IL (i.e., can be seen in
> the output of -fdump-tree-optimized or whatever pass the warning runs in)
> the warning triggers.  Taking the conditions into consideration and issuing
> "maybe" kinds of warnings (like -Wmaybe-uninitialized) is a work in progress
> but as of now no warning other thanb -Wmaybe-uninitialized does.

Ok, then please consider this bug as a case for adding consideration of
conditions.

> No such distinction as "there's definitely a bug" vs "there may be a bug" is
> feasible because there is, in general, no way to identify functions that are
> defined but never called, or those that are only called with arguments that
> make certain code paths unreachable.  As a result, with few exceptions every
> GCC warning is of the latter kind.

To clarify, what I mean by "there's definitely a bug" kind of warning is when
the compiler has enough data to prove that the operation will result in UB (for
example, cause a buffer overflow). Such as:

    char* alloc_string(size_t n)
    {
        char* p = new char[n]; // forgot about the byte for the terminating 0
        std::memset(p, 0, n + 1);
        return p;
    }

This is notably different from compiler trying to reason about a possible value
of n based on size_t range and issuing warnings based on that. I would like to
see warnings of the former kind but not so much of the latter kind.

If there is no way to separate the two kinds of warnings, and the compiler does
not consider prior conditions that are written *specifically* to prevent UB
that triggers the warning, I'm afraid, I don't see the use for such warnings.

> If you're interested, the following
> two-part article discusses some of the challenges in this area:
> 
> https://developers.redhat.com/blog/2019/03/13/understanding-gcc-warnings/
> https://developers.redhat.com/blog/2019/03/13/understanding-gcc-warnings-
> part-2/

Thanks, I will read it. I understand that compiler warnings are not easy to
implement right.

> If the #pragma suppression doesn't work with LTO please report that as a
> separate bug.  There's nothing we can do to avoid the warning in this case.

The fact that pragmas don't work with LTO is documented in the -flto
description[1]. My impression is that gcc simply doesn't support warning
control through pragmas when LTO is enabled. Is this not the case?

I can create a bug, but I cannot provide a small repro, since the warning
triggers in a large code base, but not necessarily a small test case. Would
such a bug report be useful?

[1]: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-flto

Reply via email to