[Bug c++/85783] alloc-size-larger-than fires incorrectly with new[] and can't be disabled
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue May 15 01:21:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85783
Martin Sebor <msebor at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |diagnostic
Status|UNCONFIRMED |RESOLVED
CC| |msebor at gcc dot gnu.org
Resolution|--- |WONTFIX
--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
I can reproduce it with the following reduced semi-valid test case. (The test
case isn't entirely valid because it defines the array new to exit on failure
rather than to throw, but a nothrow form of the test case reproduces the
warning as well.)
void* operator new[](__SIZE_TYPE__ n)
{
void* p = __builtin_malloc (n);
if (p)
return p;
__builtin_exit (1);
}
struct A
{
A ();
~A ();
};
void* f (__SIZE_TYPE__ n)
{
if (!n)
return 0;
return new A[n];
}
In function ‘void* operator new [](long unsigned int)’,
inlined from ‘void* f(long unsigned int)’ at pr85783.C:22:17:
pr85783.C:3:30: warning: argument 1 value ‘18446744073709551615’ exceeds
maximum object size 9223372036854775807 [-Walloc-size-larger-than=]
void* p = __builtin_malloc (n);
~~~~~~~~~~~~~~~~~^~~
pr85783.C: In function ‘void* f(long unsigned int)’:
pr85783.C:3:30: note: in a call to built-in allocation function ‘void*
__builtin_malloc(long unsigned int)’
The excessive constant argument is introduced by the C++ front-end, in
cp/build_operator_new_call(), which emits a call to operator new[](size_t).
The code was added in r190546 as a solution to prevent unsigned wrapping (when
array new expression must compute the amount of space to allocate as a product
of the number of elements and element size). When the replacement operator
new[] is inlined the excessive argument is propagated to malloc() and
ultimately triggers the warning.
An easy way to suppress the warning is to check the argument in the operator
and have it fail when it's excessive:
void* operator new[](size_t n)
{
if (n <= PTRDIFF_MAX)
{
void* p = malloc (n);
if (p)
return p;
}
exit (1);
}
Otherwise, I'm not sure there is much GCC can do to avoid the warning, or that
it's worth putting effort into. The use case (defining a non-throwing
replacement operator new inline) is rare and not entirely valid. Normally, the
operator will be defined out-of-line and while that might still trigger
warnings from the same translation unit, the solution -- handling the excessive
argument in the replacement operator -- seems simple enough.
With that I'm going to resolve this report as WONTFIX. If someone (e.g., Jeff
who chimed in on the discussion on gcc-help below) feels otherwise please feel
free to reopen it.
https://gcc.gnu.org/ml/gcc-help/2018-05/msg00088.html
More information about the Gcc-bugs
mailing list