https://gcc.gnu.org/g:efc795b32417e68acfe531762c7bcf893e6dd672
commit efc795b32417e68acfe531762c7bcf893e6dd672 Author: Thomas Schwinge <tschwi...@baylibre.com> Date: Wed Mar 19 12:18:26 2025 +0100 C++: Adjust implicit '__cxa_bad_typeid' prototype to reality In 2001 Subversion r40924 (Git commit 52a11cbfcf0cfb32628b6953588b6af4037ac0b6) "IA-64 ABI Exception Handling", '__cxa_bad_typeid' changed from 'std::type_info const &' 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" std::type_info const & -__cxa_bad_typeid () -{ - [...] -} -[...] --- /dev/null +++ libstdc++-v3/libsupc++/unwind-cxx.h @@ -0,0 +1,163 @@ +[...] +extern "C" void __cxa_bad_typeid (); +[...] --- /dev/null +++ libstdc++-v3/libsupc++/eh_aux_runtime.cc @@ -0,0 +1,56 @@ +[...] +extern "C" void +__cxa_bad_typeid () +{ + [...] +} The implicit prototype in the C++ front end however wasn't likewise adjusted, and so for nvptx we generate code for 'std::type_info const &' return type: // BEGIN GLOBAL FUNCTION DECL: __cxa_bad_typeid .extern .func (.param .u64 %value_out) __cxa_bad_typeid; { .param .u64 %value_in; call (%value_in),__cxa_bad_typeid; trap; // (noreturn) exit; // (noreturn) ld.param.u64 %r39,[%value_in]; } ..., which is in conflict with the library code with 'void' return type: // BEGIN GLOBAL FUNCTION DECL: __cxa_bad_typeid .visible .func __cxa_bad_typeid; // BEGIN GLOBAL FUNCTION DEF: __cxa_bad_typeid .visible .func __cxa_bad_typeid { [...] } ..., and we thus get execution test FAILs for 'g++.dg/rtti/typeid11.C', for example: error : Prototype doesn't match for '__cxa_bad_typeid' in 'input file 4 at offset 22204', first defined in 'input file 4 at offset 22204' nvptx-run: cuLinkAddData failed: unknown error (CUDA_ERROR_UNKNOWN, 999) With this patched, we get the expected: // BEGIN GLOBAL FUNCTION DECL: __cxa_bad_typeid -.extern .func (.param .u64 %value_out) __cxa_bad_typeid; +.extern .func __cxa_bad_typeid; { -.param .u64 %value_in; -call (%value_in),__cxa_bad_typeid; +call __cxa_bad_typeid; trap; // (noreturn) exit; // (noreturn) -ld.param.u64 %r39,[%value_in]; } ..., and execution test PASSes for a few test cases. gcc/cp/ * rtti.cc (throw_bad_typeid): Adjust implicit '__cxa_bad_typeid' prototype to reality. Adjust all users. Co-authored-by: Jason Merrill <ja...@redhat.com> (cherry picked from commit bf1aca4a2a5b68ac731d2a0c966f335e7bc0df2c) Diff: --- gcc/cp/ChangeLog.omp | 9 +++++++++ gcc/cp/rtti.cc | 18 +++++++----------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/gcc/cp/ChangeLog.omp b/gcc/cp/ChangeLog.omp index e37a4344ca47..d581e233f71d 100644 --- a/gcc/cp/ChangeLog.omp +++ b/gcc/cp/ChangeLog.omp @@ -1,3 +1,12 @@ +2025-03-27 Thomas Schwinge <tschwi...@baylibre.com> + + Backported from trunk: + 2025-03-26 Thomas Schwinge <tschwi...@baylibre.com> + Jason Merrill <ja...@redhat.com> + + * rtti.cc (throw_bad_typeid): Adjust implicit '__cxa_bad_typeid' + prototype to reality. Adjust all users. + 2025-03-25 Thomas Schwinge <tschwi...@baylibre.com> Backported from trunk: diff --git a/gcc/cp/rtti.cc b/gcc/cp/rtti.cc index e07cc01fd0ba..99a5e51355b8 100644 --- a/gcc/cp/rtti.cc +++ b/gcc/cp/rtti.cc @@ -204,8 +204,7 @@ throw_bad_cast (void) return build_cxx_call (fn, 0, NULL, tf_warning_or_error); } -/* Return an expression for "__cxa_bad_typeid()". The expression - returned is an lvalue of type "const std::type_info". */ +/* See 'libstdc++-v3/libsupc++/eh_aux_runtime.cc' for '__cxa_bad_typeid'. */ static tree throw_bad_typeid (void) @@ -216,11 +215,8 @@ throw_bad_typeid (void) tree name = get_identifier ("__cxa_bad_typeid"); fn = get_global_binding (name); if (!fn) - { - tree t = build_reference_type (const_type_info_type_node); - t = build_function_type_list (t, NULL_TREE); - fn = push_throw_library_fn (name, t); - } + fn = push_throw_library_fn + (name, build_function_type_list (void_type_node, NULL_TREE)); } return build_cxx_call (fn, 0, NULL, tf_warning_or_error); @@ -259,7 +255,7 @@ get_void_tinfo_ptr (tree type) otherwise return the static type of the expression. */ static tree -get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain) +get_tinfo_ptr_dynamic (tree exp, tsubst_flags_t complain) { tree type; tree t; @@ -299,7 +295,7 @@ get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain) /* Otherwise return the type_info for the static type of the expr. */ t = get_tinfo_ptr (type); - return cp_build_fold_indirect_ref (t); + return t; } static bool @@ -369,7 +365,7 @@ build_typeid (tree exp, tsubst_flags_t complain) exp = cp_build_fold_indirect_ref (exp); } - exp = get_tinfo_decl_dynamic (exp, complain); + exp = get_tinfo_ptr_dynamic (exp, complain); if (exp == error_mark_node) return error_mark_node; @@ -383,7 +379,7 @@ build_typeid (tree exp, tsubst_flags_t complain) else mark_type_use (initial_expr); - return exp; + return cp_build_fold_indirect_ref (exp); } /* Generate the NTBS name of a type. If MARK_PRIVATE, put a '*' in front so that