From: Martin Sebor Date: Mon, 12 Oct 2020 15:35:02 +0000 (-0600) Subject: PR c++/97201 - ICE in -Warray-bounds writing to result of operator new(0) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1be51a3a9ac3409561223c8058d4943f9b574d15;p=gcc.git PR c++/97201 - ICE in -Warray-bounds writing to result of operator new(0) gcc/cp/ChangeLog: PR c++/97201 * error.c (dump_type_suffix): Handle both the C and C++ forms of zero-length arrays. libstdc++-v3/ChangeLog: PR c++/97201 * libsupc++/new (operator new): Add attribute alloc_size and malloc. gcc/testsuite/ChangeLog: PR c++/97201 * g++.dg/warn/Wplacement-new-size-8.C: Adjust expected message. * g++.dg/warn/Warray-bounds-10.C: New test. * g++.dg/warn/Warray-bounds-11.C: New test. * g++.dg/warn/Warray-bounds-12.C: New test. * g++.dg/warn/Warray-bounds-13.C: New test. --- diff --git a/gcc/cp/error.c b/gcc/cp/error.c index ad22b00cb0b..396558be17f 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -951,8 +951,11 @@ dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags) if (tree dtype = TYPE_DOMAIN (t)) { tree max = TYPE_MAX_VALUE (dtype); - /* Zero-length arrays have an upper bound of SIZE_MAX. */ - if (integer_all_onesp (max)) + /* Zero-length arrays have a null upper bound in C and SIZE_MAX + in C++. Handle both since the type might be constructed by + the middle end and end up here as a result of a warning (see + PR c++/97201). */ + if (!max || integer_all_onesp (max)) pp_character (pp, '0'); else if (tree_fits_shwi_p (max)) pp_wide_integer (pp, tree_to_shwi (max) + 1); diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C new file mode 100644 index 00000000000..22466977b68 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C @@ -0,0 +1,64 @@ +/* PR c++/97201 - ICE in -Warray-bounds writing to result of operator new(0) + Verify that out-of-bounds accesses to memory returned by default operator + new() are diagnosed. + { dg-do compile } + { dg-options "-O2 -Wall -Warray-bounds -ftrack-macro-expansion=0" } */ + +typedef __INT32_TYPE__ int32_t; + +void sink (void*); + +#define OP_NEW(n) operator new (n) +#define T(T, n, i) do { \ + T *p = (T*) OP_NEW (n); \ + p[i] = 0; \ + sink (p); \ + } while (0) + +void warn_op_new () +{ + T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" } + // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new\\\(\(long \)?unsigned int\\\)'" "note" { target *-*-* } .-1 } + T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" } + T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" } + T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" } + + T (int32_t, 4, 0); + + T (int32_t, 0, 1); // { dg-warning "array subscript 1 is outside array bounds of 'int32_t \\\[0]'" } + T (int32_t, 1, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 2, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 3, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 4, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 5, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[5]" } + T (int32_t, 6, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[6]" } + T (int32_t, 7, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[7]" } + + T (int32_t, 8, 1); +} + + +void warn_op_array_new () +{ +#undef OP_NEW +#define OP_NEW(n) operator new[] (n) + + T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" } + // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new \\\[]\\\(\(long \)?unsigned int\\\)'" "note" { target *-*-* } .-1 } + T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" } + T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" } + T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" } + + T (int32_t, 4, 0); + + T (int32_t, 0, 1); // { dg-warning "array subscript 1 is outside array bounds of 'int32_t \\\[0]'" } + T (int32_t, 1, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 2, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 3, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 4, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 5, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[5]" } + T (int32_t, 6, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[6]" } + T (int32_t, 7, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[7]" } + + T (int32_t, 8, 1); +} diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-11.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-11.C new file mode 100644 index 00000000000..9875e29085d --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-11.C @@ -0,0 +1,66 @@ +/* PR c++/97201 - ICE in -Warray-bounds writing to result of operator new(0) + Verify that out-of-bounds accesses to memory returned by nothrow operator + new() are diagnosed. + { dg-do compile } + { dg-options "-O2 -Wall -Warray-bounds -ftrack-macro-expansion=0" } */ + +#include + +typedef __INT32_TYPE__ int32_t; + +void sink (void*); + +#define OP_NEW(n) operator new (n, std::nothrow) +#define T(T, n, i) do { \ + T *p = (T*) OP_NEW (n); \ + p[i] = 0; \ + sink (p); \ + } while (0) + +void warn_op_new () +{ + T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" } + // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new\\\(std::size_t, const std::nothrow_t.\\\)'" "note" { target *-*-* } .-1 } + T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" } + T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" } + T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" } + + T (int32_t, 4, 0); + + T (int32_t, 0, 1); // { dg-warning "array subscript 1 is outside array bounds of 'int32_t \\\[0]'" } + T (int32_t, 1, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 2, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 3, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 4, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 5, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[5]" } + T (int32_t, 6, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[6]" } + T (int32_t, 7, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[7]" } + + T (int32_t, 8, 1); +} + + +void warn_op_array_new () +{ +#undef OP_NEW +#define OP_NEW(n) operator new[] (n, std::nothrow) + + T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" } + // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new \\\[]\\\(std::size_t, const std::nothrow_t&\\\)'" "note" { target *-*-* } .-1 } + T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" } + T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" } + T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" } + + T (int32_t, 4, 0); + + T (int32_t, 0, 1); // { dg-warning "array subscript 1 is outside array bounds of 'int32_t \\\[0]'" } + T (int32_t, 1, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 2, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 3, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 4, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 5, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[5]" } + T (int32_t, 6, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[6]" } + T (int32_t, 7, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[7]" } + + T (int32_t, 8, 1); +} diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-12.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-12.C new file mode 100644 index 00000000000..9e8b6048944 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-12.C @@ -0,0 +1,66 @@ +/* PR c++/97201 - ICE in -Warray-bounds writing to result of operator new(0) + Verify that out-of-bounds accesses to memory returned by the new expression + are diagnosed. + { dg-do compile } + { dg-options "-O2 -Wall -Warray-bounds -ftrack-macro-expansion=0" } */ + +typedef __INT32_TYPE__ int32_t; + +template struct S { char a[N]; }; + +void sink (void*); + +#define NEW(n) new S +#define T(T, n, i) do { \ + T *p = (T*)NEW (n); \ + p[i] = 0; \ + sink (p); \ + } while (0) + +void warn_new () +{ + T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" } + // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new\\\(\(long \)?unsigned int\\\)'" "note" { target *-*-* } .-1 } + T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" } + T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" } + T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" } + + T (int32_t, 4, 0); + + T (int32_t, 0, 1); // { dg-warning "array subscript 1 is outside array bounds of 'int32_t \\\[0]'" } + T (int32_t, 1, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 2, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 3, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 4, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 5, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[5]" } + T (int32_t, 6, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[6]" } + T (int32_t, 7, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[7]" } + + T (int32_t, 8, 1); +} + + +void warn_array_new () +{ +#undef NEW +#define NEW(n) new char [n] + + T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" } + // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new \\\[]\\\(\(long \)?unsigned int\\\)'" "note" { target *-*-* } .-1 } + T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" } + T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" } + T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" } + + T (int32_t, 4, 0); + + T (int32_t, 0, 1); // { dg-warning "array subscript 1 is outside array bounds of 'int32_t \\\[0]'" } + T (int32_t, 1, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 2, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 3, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 4, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 5, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[5]" } + T (int32_t, 6, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[6]" } + T (int32_t, 7, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[7]" } + + T (int32_t, 8, 1); +} diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-13.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-13.C new file mode 100644 index 00000000000..42fb809de3c --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-13.C @@ -0,0 +1,70 @@ +/* PR c++/97201 - ICE in -Warray-bounds writing to result of operator new(0) + Verify that out-of-bounds accesses to memory returned by the nothrow form + of the new expression are diagnosed. + { dg-do compile } + { dg-options "-O2 -Wall -Warray-bounds -ftrack-macro-expansion=0" } */ + +#include + +typedef __INT32_TYPE__ int32_t; + +void sink (void*); + +template struct S { char a[N]; }; + +void sink (void*); + +#define NEW(n) new (std::nothrow) S +#define T(T, n, i) do { \ + T *p = (T*)NEW (n); \ + p[i] = 0; \ + sink (p); \ + } while (0) + +void warn_nothrow_new () +{ + T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" } + // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new\\\(std::size_t, const std::nothrow_t.\\\)'" "note" { target *-*-* } .-1 } + T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" } + T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" } + T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" } + + T (int32_t, 4, 0); + + T (int32_t, 0, 1); // { dg-warning "array subscript 1 is outside array bounds of 'int32_t \\\[0]'" } + T (int32_t, 1, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 2, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 3, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 4, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 5, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[5]" } + T (int32_t, 6, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[6]" } + T (int32_t, 7, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[7]" } + + T (int32_t, 8, 1); +} + + +void warn_nothrow_array_new () +{ +#undef NEW +#define NEW(n) new (std::nothrow) char [n] + + T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" } + // { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new \\\[]\\\(std::size_t, const std::nothrow_t&\\\)'" "note" { target *-*-* } .-1 } + T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" } + T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" } + T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" } + + T (int32_t, 4, 0); + + T (int32_t, 0, 1); // { dg-warning "array subscript 1 is outside array bounds of 'int32_t \\\[0]'" } + T (int32_t, 1, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 2, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 3, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 4, 1); // { dg-warning "array subscript 1 is outside array bounds " } + T (int32_t, 5, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[5]" } + T (int32_t, 6, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[6]" } + T (int32_t, 7, 1); // { dg-warning "array subscript 'int32_t {aka int}\\\[1]' is partly outside array bounds of 'unsigned char \\\[7]" } + + T (int32_t, 8, 1); +} diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-8.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-8.C index a0d136266ea..77bd3314a19 100644 --- a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-8.C +++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-8.C @@ -138,7 +138,7 @@ void test_var_off_schar (signed char i) } { - char a[65281]; // { dg-message "at offset \\\[65153, 65408] from 'a'" } + char a[65281]; // { dg-message "at offset \\\[65153, 65281] from 'a'" "note" } new (a + i + 65280) S<1>; new (a + i + 65281) S<1>; new (a + i + 65281) S<128>; diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new index 21848a573d1..15edf8ad6a9 100644 --- a/libstdc++-v3/libsupc++/new +++ b/libstdc++-v3/libsupc++/new @@ -138,26 +138,26 @@ void operator delete[](void*, std::size_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); #endif _GLIBCXX_NODISCARD void* operator new(std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT - __attribute__((__externally_visible__, __malloc__)); + __attribute__((__externally_visible__, __alloc_size__ (1), __malloc__)); _GLIBCXX_NODISCARD void* operator new[](std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT - __attribute__((__externally_visible__, __malloc__)); + __attribute__((__externally_visible__, __alloc_size__ (1), __malloc__)); void operator delete(void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); #if __cpp_aligned_new _GLIBCXX_NODISCARD void* operator new(std::size_t, std::align_val_t) - __attribute__((__externally_visible__)); + __attribute__((__externally_visible__, __alloc_size__ (1), __malloc__)); _GLIBCXX_NODISCARD void* operator new(std::size_t, std::align_val_t, const std::nothrow_t&) - _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__, __malloc__)); + _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__, __alloc_size__ (1), __malloc__)); void operator delete(void*, std::align_val_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete(void*, std::align_val_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); _GLIBCXX_NODISCARD void* operator new[](std::size_t, std::align_val_t) - __attribute__((__externally_visible__)); + __attribute__((__externally_visible__, __alloc_size__ (1), __malloc__)); _GLIBCXX_NODISCARD void* operator new[](std::size_t, std::align_val_t, const std::nothrow_t&) - _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__, __malloc__)); + _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__, __alloc_size__ (1), __malloc__)); void operator delete[](void*, std::align_val_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, std::align_val_t, const std::nothrow_t&)