[PATCH] C++: Adjust implicit '__cxa_bad_cast' prototype to reality
Marek Polacek
polacek@redhat.com
Wed Mar 19 14:20:44 GMT 2025
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.
Marek
More information about the Libstdc++
mailing list