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

Reply via email to