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