Skip to content
Snippets Groups Projects
Commit e5d8fd9c authored by Jakub Jelinek's avatar Jakub Jelinek
Browse files

c++, mingw: Fix up types of dtor hooks to __cxa_{,thread_}atexit/__cxa_throw...

c++, mingw: Fix up types of dtor hooks to __cxa_{,thread_}atexit/__cxa_throw on mingw ia32 [PR114968]

__cxa_atexit/__cxa_thread_atexit/__cxa_throw functions accept function
pointers to usually directly destructors rather than wrappers around
them.
Now, mingw ia32 uses implicitly __attribute__((thiscall)) calling
conventions for METHOD_TYPE (where the this pointer is passed in %ecx
register, the rest on the stack), so these functions use:
in config/os/mingw32/os_defines.h:
 #if defined (__i386__)
 #define _GLIBCXX_CDTOR_CALLABI __thiscall
 #endif
in libsupc++/cxxabi.h
__cxa_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*, void*) _GLIBCXX_NOTHROW;
__cxa_thread_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*, void *) _GLIBCXX_NOTHROW;
__cxa_throw(void*, std::type_info*, void (_GLIBCXX_CDTOR_CALLABI *) (void *))
__attribute__((__noreturn__));

Now, mingw for some weird reason uses
 #define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_true
so it never actually uses __cxa_atexit, but does use __cxa_thread_atexit
and __cxa_throw.  Recent changes for modules result in more detailed
__cxa_*atexit/__cxa_throw prototypes precreated by the compiler, and if
that happens and one also includes <cxxabi.h>, the compiler complains about
mismatches in the prototypes.

One thing is the missing thiscall attribute on the FUNCTION_TYPE, the
other problem is that all of atexit/__cxa_atexit/__cxa_thread_atexit
get function pointer types created by a single function,
get_atexit_fn_ptr_type (), which creates it depending on if atexit
or __cxa_atexit will be used as either void(*)(void) or void(*)(void *),
but when using atexit and __cxa_thread_atexit it uses the wrong function
type for __cxa_thread_atexit.

The following patch adds a target hook to add the thiscall attribute to the
function pointers, and splits the get_atexit_fn_ptr_type () function into
get_atexit_fn_ptr_type () and get_cxa_atexit_fn_ptr_type (), the former always
creates shared void(*)(void) type, the latter creates either
void(*)(void*) (on most targets) or void(__attribute__((thiscall))*)(void*)
(on mingw ia32).  So that we don't waiste another GTY global tree for it,
because cleanup_type used for the same purpose for __cxa_throw should be
the same, the code changes it to use that type too.

In register_dtor_fn then based on the decision whether to use atexit,
__cxa_atexit or __cxa_thread_atexit it picks the right function pointer
type, and also if it decides to emit a __tcf_* wrapper for the cleanup,
uses that type for that wrapper so that it agrees on calling convention.

2024-05-10  Jakub Jelinek  <jakub@redhat.com>

	PR target/114968
gcc/
	* target.def (use_atexit_for_cxa_atexit): Remove spurious space
	from comment.
	(adjust_cdtor_callabi_fntype): New cxx target hook.
	* targhooks.h (default_cxx_adjust_cdtor_callabi_fntype): Declare.
	* targhooks.cc (default_cxx_adjust_cdtor_callabi_fntype): New
	function.
	* doc/tm.texi.in (TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE): Add.
	* doc/tm.texi: Regenerate.
	* config/i386/i386.cc (ix86_cxx_adjust_cdtor_callabi_fntype): New
	function.
	(TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE): Redefine.
gcc/cp/
	* cp-tree.h (atexit_fn_ptr_type_node, cleanup_type): Adjust macro
	comments.
	(get_cxa_atexit_fn_ptr_type): Declare.
	* decl.cc (get_atexit_fn_ptr_type): Adjust function comment, only
	build type for atexit argument.
	(get_cxa_atexit_fn_ptr_type): New function.
	(get_atexit_node): Call get_cxa_atexit_fn_ptr_type rather than
	get_atexit_fn_ptr_type when using __cxa_atexit.
	(get_thread_atexit_node): Call get_cxa_atexit_fn_ptr_type
	rather than get_atexit_fn_ptr_type.
	(start_cleanup_fn): Add ob_parm argument, call
	get_cxa_atexit_fn_ptr_type or get_atexit_fn_ptr_type depending
	on it and create PARM_DECL also based on that argument.
	(register_dtor_fn): Adjust start_cleanup_fn caller, use
	get_cxa_atexit_fn_ptr_type rather than get_atexit_fn_ptr_type
	for use_dtor casts.
	* except.cc (build_throw): Use get_cxa_atexit_fn_ptr_type ().
parent ac255c7a
No related branches found
No related tags found
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment