On 3/19/25 1:35 PM, Thomas Schwinge wrote:
Hi Jason!
On 2013-05-03T16:24:43-0400, Jason Merrill <ja...@redhat.com> wrote:
Last year Florian fixed the compiler to detect overflow in array new
size calculations and pass (size_t)-1 in that case. But C++11 specifies
that in case of overflow the program throws std::bad_array_new_length
(http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#624), so
I've adjusted the checking code accordingly.
This patch also adds the type to libsupc++, and several exports to
libstdc++.
Tested x86_64-pc-linux-gnu, applying to trunk.
Subversion r198731 (Git commit 7d5e76c8de1b6c4b2ae5576ab909dc9e580b216b).
Core 624/N2932: Throw bad_array_new_length on overflow
in array new size calculation.
libstdc++-v3/
* libsupc++/new: Add std::bad_array_new_length.
* libsupc++/bad_array_new.cc: New.
* libsupc++/eh_aux_runtime.cc: Add __cxa_bad_array_new_length.
* libsupc++/Makefile.in: Build them.
* config/abi/pre/gnu.ver: Add new symbols.
* config/abi/pre/gnu-versioned-namespace.ver: Add new symbols.
gcc/cp/
* init.c (throw_bad_array_new_length): New.
(build_new_1): Use it. Don't warn about braced-init-list.
(build_vec_init): Use it.
* call.c (build_operator_new_call): Use it.
Here:
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
+/* Call __cxa_bad_array_new_length to indicate that the size calculation
+ overflowed. Pretend it returns sizetype so that it plays nicely in the
+ COND_EXPR. */
+
+tree
+throw_bad_array_new_length (void)
+{
+ tree fn = get_identifier ("__cxa_bad_array_new_length");
+ if (!get_global_value_if_present (fn, &fn))
+ fn = push_throw_library_fn (fn, build_function_type_list (sizetype,
+ NULL_TREE));
+
+ return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
+}
"Pretend it returns sizetype", doesn't work with nvptx, which complains
that the front end-synthesized prototype with the fake 'sizetype' return
type:
.extern .func (.param .u64 %value_out) __cxa_throw_bad_array_new_length;
... doesn't match the library code with 'void' return type:
--- a/libstdc++-v3/libsupc++/cxxabi.h
+++ b/libstdc++-v3/libsupc++/cxxabi.h
+ void
+ __cxa_bad_array_new_length() __attribute__((__noreturn__));
--- a/libstdc++-v3/libsupc++/eh_aux_runtime.cc
+++ b/libstdc++-v3/libsupc++/eh_aux_runtime.cc
+extern "C" void
+__cxxabiv1::__cxa_bad_array_new_length ()
+{ _GLIBCXX_THROW_OR_ABORT(std::bad_array_new_length()); }
.visible .func __cxa_throw_bad_array_new_length
{
[...]
}
..., and thus results in execution test FAILs:
error : Prototype doesn't match for '__cxa_throw_bad_array_new_length'
in 'input file 5 at offset 14095', first defined in 'input file 5 at offset
14095'
nvptx-run: cuLinkAddData failed: device kernel image is invalid
(CUDA_ERROR_INVALID_SOURCE, 300)
How can we improve on "Pretend it returns sizetype"? Is there a standard
way to "bend" the types in the front end?
Seems like we can just fix the return type, I don't see any regressions
from this:
From cfc6e295ea19cb570c06d3281f41fd5ae0ba076b Mon Sep 17 00:00:00 2001
From: Jason Merrill <ja...@redhat.com>
Date: Thu, 20 Mar 2025 09:55:40 -0400
Subject: [PATCH] c++: fix return typye of __cxa_bad_array_new_length
To: gcc-patches@gcc.gnu.org
We were lying about the return type, but that's not necessary; we already
need to handle a COND_EXPR where one side is void for THROW_EXPR.
gcc/cp/ChangeLog:
* init.cc (throw_bad_array_new_length): Returns void.
---
gcc/cp/init.cc | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index ce6e58e05f2..e589e45e891 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -2810,8 +2810,7 @@ diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new, bool compla
}
/* Call __cxa_bad_array_new_length to indicate that the size calculation
- overflowed. Pretend it returns sizetype so that it plays nicely in the
- COND_EXPR. */
+ overflowed. */
tree
throw_bad_array_new_length (void)
@@ -2823,7 +2822,7 @@ throw_bad_array_new_length (void)
fn = get_global_binding (name);
if (!fn)
fn = push_throw_library_fn
- (name, build_function_type_list (sizetype, NULL_TREE));
+ (name, build_function_type_list (void_type_node, NULL_TREE));
}
return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
--
2.48.1