Hi!

On 2025-03-19T14:25:49+0000, Jonathan Wakely <jwakely....@gmail.com> wrote:
> On Wed, 19 Mar 2025 at 14:21, Marek Polacek <pola...@redhat.com> wrote:
>> On Wed, Mar 19, 2025 at 12:38:31PM +0100, Thomas Schwinge wrote:
>> > In 2001 Subversion r40924 (Git commit 
>> > 52a11cbfcf0cfb32628b6953588b6af4037ac0b6)
>> > "IA-64 ABI Exception Handling", '__cxa_bad_cast' changed from 'void *' to
>> > 'void' return type:
>> >
>> >     --- libstdc++-v3/libsupc++/exception_support.cc
>> >     +++ /dev/null
>> >     @@ -1,388 +0,0 @@
>> >     -[...]
>> >     -// Helpers for rtti. Although these don't return, we give them return 
>> > types so
>> >     -// that the type system is not broken.
>> >     -extern "C" void *
>> >     -__cxa_bad_cast ()
>> >     -{
>> >     -  [...]
>> >     -}
>> >     -[...]
>> >
>> >     --- /dev/null
>> >     +++ libstdc++-v3/libsupc++/unwind-cxx.h
>> >     @@ -0,0 +1,163 @@
>> >     +[...]
>> >     +extern "C" void __cxa_bad_cast ();
>> >     +[...]
>> >
>> >     --- /dev/null
>> >     +++ libstdc++-v3/libsupc++/eh_aux_runtime.cc
>> >     @@ -0,0 +1,56 @@
>> >     +[...]
>> >     +extern "C" void
>> >     +__cxa_bad_cast ()
>> >     +{
>> >     +  [...]
>> >     +}
>> >     +[...]
>> >
>> > The implicit prototype in the C++ front end however wasn't likewise 
>> > adjusted,
>> > and so for nvptx we generate code for 'void *' return type:
>> >
>> >     // BEGIN GLOBAL FUNCTION DECL: __cxa_bad_cast
>> >     .extern .func (.param .u64 %value_out) __cxa_bad_cast;
>> >
>> >     {
>> >     .param .u64 %value_in;
>> >     call (%value_in),__cxa_bad_cast;
>> >     trap;
>> >     // (noreturn)
>> >     exit;
>> >     // (noreturn)
>> >     ld.param.u64 %r30,[%value_in];
>> >     }
>> >
>> > ..., which is in conflict with the library code with 'void' return type:
>> >
>> >     // BEGIN GLOBAL FUNCTION DECL: __cxa_bad_cast
>> >     .visible .func __cxa_bad_cast;
>> >
>> >     // BEGIN GLOBAL FUNCTION DEF: __cxa_bad_cast
>> >     .visible .func __cxa_bad_cast
>> >     {
>> >     [...]
>> >     }
>> >
>> > ..., and we thus get execution test FAIL for 'g++.dg/rtti/dyncast2.C':
>> >
>> >     error   : Prototype doesn't match for '__cxa_bad_cast' in 'input file 
>> > 7 at offset 51437', first defined in 'input file 7 at offset 51437'
>> >     nvptx-run: cuLinkAddData failed: device kernel image is invalid 
>> > (CUDA_ERROR_INVALID_SOURCE, 300)
>> >
>> > With this patched, we get the expected:
>> >
>> >      // BEGIN GLOBAL FUNCTION DECL: __cxa_bad_cast
>> >     -.extern .func (.param .u64 %value_out) __cxa_bad_cast;
>> >     +.extern .func __cxa_bad_cast;
>> >
>> >      {
>> >     -.param .u64 %value_in;
>> >     -call (%value_in),__cxa_bad_cast;
>> >     +call __cxa_bad_cast;
>> >      trap;
>> >      // (noreturn)
>> >      exit;
>> >      // (noreturn)
>> >     -ld.param.u64 %r30,[%value_in];
>> >      }
>> >
>> > ..., and execution test PASS.
>> >
>> >       gcc/cp/
>> >       * rtti.cc (throw_bad_cast): Adjust implicit '__cxa_bad_cast'
>> >       prototype to reality.
>> > ---
>> >  gcc/cp/rtti.cc | 2 +-
>> >  1 file changed, 1 insertion(+), 1 deletion(-)
>> >
>> > diff --git a/gcc/cp/rtti.cc b/gcc/cp/rtti.cc
>> > index dcf84f17163..a10fa383f79 100644
>> > --- a/gcc/cp/rtti.cc
>> > +++ b/gcc/cp/rtti.cc
>> > @@ -198,7 +198,7 @@ throw_bad_cast (void)
>> >        fn = get_global_binding (name);
>> >        if (!fn)
>> >       fn = push_throw_library_fn
>> > -       (name, build_function_type_list (ptr_type_node, NULL_TREE));
>> > +       (name, build_function_type_list (void_type_node, NULL_TREE));
>> >      }
>> >
>> >    return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
>>
>> LGTM, matches what I see in abi-eh.html from the itanium-cxx-abi.
>>
>> The comment above mentions libstdc++/exception.cc but I don't see that
>> file.
>
> I think that was removed in 2001 by r39445 :-)

Yeah, I'd noticed that right after (of course) having sent my original
email; fixed in the "v2" that I've now pushed to trunk branch:
commit 618c42d23726be6e2086d452d6718abe5e0daca8
"C++: Adjust implicit '__cxa_bad_cast' prototype to reality", see
attached.

By the way, I've also tested this with 'fn = get_global_binding (name);'
commented out, to force always using the C++ front end-synthesized
prototype (per my understanding).

I've just realized that we might check if some users of 'throw_bad_cast'
have special code to handle the case of 'void *' return type in addition
to 'void', which can now be simplified -- I'll try to look into that next
week.


Grüße
 Thomas


>From 618c42d23726be6e2086d452d6718abe5e0daca8 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <tschwi...@baylibre.com>
Date: Wed, 19 Mar 2025 12:18:26 +0100
Subject: [PATCH] C++: Adjust implicit '__cxa_bad_cast' prototype to reality

In 2001 Subversion r40924 (Git commit 52a11cbfcf0cfb32628b6953588b6af4037ac0b6)
"IA-64 ABI Exception Handling", '__cxa_bad_cast' changed from 'void *' to
'void' return type:

    --- libstdc++-v3/libsupc++/exception_support.cc
    +++ /dev/null
    @@ -1,388 +0,0 @@
    -[...]
    -// Helpers for rtti. Although these don't return, we give them return types so
    -// that the type system is not broken.
    -extern "C" void *
    -__cxa_bad_cast ()
    -{
    -  [...]
    -}
    -[...]

    --- /dev/null
    +++ libstdc++-v3/libsupc++/unwind-cxx.h
    @@ -0,0 +1,163 @@
    +[...]
    +extern "C" void __cxa_bad_cast ();
    +[...]

    --- /dev/null
    +++ libstdc++-v3/libsupc++/eh_aux_runtime.cc
    @@ -0,0 +1,56 @@
    +[...]
    +extern "C" void
    +__cxa_bad_cast ()
    +{
    +  [...]
    +}
    +[...]

The implicit prototype in the C++ front end however wasn't likewise adjusted,
and so for nvptx we generate code for 'void *' return type:

    // BEGIN GLOBAL FUNCTION DECL: __cxa_bad_cast
    .extern .func (.param .u64 %value_out) __cxa_bad_cast;

    {
    .param .u64 %value_in;
    call (%value_in),__cxa_bad_cast;
    trap;
    // (noreturn)
    exit;
    // (noreturn)
    ld.param.u64 %r30,[%value_in];
    }

..., which is in conflict with the library code with 'void' return type:

    // BEGIN GLOBAL FUNCTION DECL: __cxa_bad_cast
    .visible .func __cxa_bad_cast;

    // BEGIN GLOBAL FUNCTION DEF: __cxa_bad_cast
    .visible .func __cxa_bad_cast
    {
    [...]
    }

..., and we thus get execution test FAIL for 'g++.dg/rtti/dyncast2.C':

    error   : Prototype doesn't match for '__cxa_bad_cast' in 'input file 7 at offset 51437', first defined in 'input file 7 at offset 51437'
    nvptx-run: cuLinkAddData failed: device kernel image is invalid (CUDA_ERROR_INVALID_SOURCE, 300)

With this patched, we get the expected:

     // BEGIN GLOBAL FUNCTION DECL: __cxa_bad_cast
    -.extern .func (.param .u64 %value_out) __cxa_bad_cast;
    +.extern .func __cxa_bad_cast;

     {
    -.param .u64 %value_in;
    -call (%value_in),__cxa_bad_cast;
    +call __cxa_bad_cast;
     trap;
     // (noreturn)
     exit;
     // (noreturn)
    -ld.param.u64 %r30,[%value_in];
     }

..., and execution test PASS.

	gcc/cp/
	* rtti.cc (throw_bad_cast): Adjust implicit '__cxa_bad_cast'
	prototype to reality.
---
 gcc/cp/rtti.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/rtti.cc b/gcc/cp/rtti.cc
index dcf84f17163..158b5ba1397 100644
--- a/gcc/cp/rtti.cc
+++ b/gcc/cp/rtti.cc
@@ -186,7 +186,7 @@ build_headof (tree exp)
 
 /* Get a bad_cast node for the program to throw...
 
-   See libstdc++/exception.cc for __throw_bad_cast */
+   See 'libstdc++-v3/libsupc++/eh_aux_runtime.cc' for '__cxa_bad_cast'.  */
 
 static tree
 throw_bad_cast (void)
@@ -198,7 +198,7 @@ throw_bad_cast (void)
       fn = get_global_binding (name);
       if (!fn)
 	fn = push_throw_library_fn
-	  (name, build_function_type_list (ptr_type_node, NULL_TREE));
+	  (name, build_function_type_list (void_type_node, NULL_TREE));
     }
 
   return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
-- 
2.34.1

Reply via email to