[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #27 from LIU Hao --- Thank you!
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 Jakub Jelinek changed: What|Removed |Added Resolution|--- |FIXED Status|UNCONFIRMED |RESOLVED --- Comment #26 from Jakub Jelinek --- Fixed then.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #25 from GCC Commits --- The releases/gcc-14 branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:a805de33f7be4f6886906ca5f4da493f3b743c76 commit r14-10193-ga805de33f7be4f6886906ca5f4da493f3b743c76 Author: Jakub Jelinek Date: Fri May 10 09:21:38 2024 +0200 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 , 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 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 (). (cherry picked from commit e5d8fd9ce05611093191d500ebc39f150d0ece2b)
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #24 from LIU Hao --- GCC 14 branch built successfully on i686-w64-mingw32 with the backported commit. I have also built boost 1.84 successfully. I'm now trying to fix the LD fault..
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #23 from LIU Hao --- I am afraid I can't do a complete bootstrap any more due to https://sourceware.org/bugzilla/show_bug.cgi?id=31720. LD is segfaulting randomly. I will backport the commit to GCC 14 branch and make a non-bootstrapped build, then build others as usual.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #22 from Jakub Jelinek --- Does even the committed version work fine on mingw32?
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #21 from GCC Commits --- The master branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:e5d8fd9ce05611093191d500ebc39f150d0ece2b commit r15-358-ge5d8fd9ce05611093191d500ebc39f150d0ece2b Author: Jakub Jelinek Date: Fri May 10 09:21:38 2024 +0200 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 , 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 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 ().
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #20 from Jakub Jelinek --- Thanks, I'll test it myself on x86_64-linux/i686-linux and post if it succeeds.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #19 from LIU Hao --- (In reply to Jakub Jelinek from comment #17) > Created attachment 58125 [details] > gcc15-pr114968.patch > > Here is an updated patch. > Note, even when not taking thiscall attribute into consideration, the > existing > code was wrong on the !targetm.cxx.use_atexit_for_cxa_atexit () targets (aka > mingw), because it would happily use the atexit function argument type (aka > void (*) ()) for __cxa_thread_atexit. Bootstrapped successfully on {i686,x86_64}-w64-mingw32. Also rebuilt mingw-w64 CRT, binutils, GDB and boost. Everything went well.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #18 from LIU Hao --- (In reply to Jakub Jelinek from comment #16) > What is the reason behind > /* mingw32 atexit function is safe to use in shared libraries. Use it >to register C++ static destructors. */ > #define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_true > ? > Couldn't we just drop that? I think so. We have a statically linked `atexit()` much like glibc [1]. However we have added `__cxa_atexit()` a couple of years ago, so it might be preferred. As the Windows system library does not provide `__cxa_*` routines, those functions are also linked statically, so they ignore the DSO handle parameter. [1] https://github.com/mingw-w64/mingw-w64/blob/19cf5d171f6df208b27271b40014c66d2b44e38b/mingw-w64-crt/crt/crtdll.c#L205 [2] https://github.com/mingw-w64/mingw-w64/blob/19cf5d171f6df208b27271b40014c66d2b44e38b/mingw-w64-crt/crt/cxa_atexit.c#L11 > while with __cxa_atexit one can just pass the destructor itself to the > __cxa_atexit function (indeed with slightly more instructions there because > in addition to the function pointer it needs to pass the address of the > object and __dso_handle). > But it is still smaller. Can `./configure --enable-__cxa_atexit` be safely used? Documentation says it's only available with glibc [3], but I don't see any stuff specific to glibc. [3] https://gcc.gnu.org/install/configure.html > Anyway, if there is some strong reason to keep it, I think it would be > better to avoid adding yet another GTY tree, the __cxa_throw last argument > type is the same as __cxa_atexit/__cxa_thread_atexit. Maybe it can be kept for backward compatibility.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 Jakub Jelinek changed: What|Removed |Added Attachment #58123|0 |1 is obsolete|| --- Comment #17 from Jakub Jelinek --- Created attachment 58125 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58125=edit gcc15-pr114968.patch Here is an updated patch. Note, even when not taking thiscall attribute into consideration, the existing code was wrong on the !targetm.cxx.use_atexit_for_cxa_atexit () targets (aka mingw), because it would happily use the atexit function argument type (aka void (*) ()) for __cxa_thread_atexit.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #16 from Jakub Jelinek --- What is the reason behind /* mingw32 atexit function is safe to use in shared libraries. Use it to register C++ static destructors. */ #define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_true ? Couldn't we just drop that? I mean, when using atexit, GCC needs to emit wrapper functions around the destructors, like __tcf_0: pushq %rbp .seh_pushreg%rbp movq%rsp, %rbp .seh_setframe %rbp, 0 subq$32, %rsp .seh_stackalloc 32 .seh_endprologue leaq_ZZ3foovE1s(%rip), %rax movq%rax, %rcx call_ZN1SD1Ev nop addq$32, %rsp popq%rbp ret while with __cxa_atexit one can just pass the destructor itself to the __cxa_atexit function (indeed with slightly more instructions there because in addition to the function pointer it needs to pass the address of the object and __dso_handle). But it is still smaller. Anyway, if there is some strong reason to keep it, I think it would be better to avoid adding yet another GTY tree, the __cxa_throw last argument type is the same as __cxa_atexit/__cxa_thread_atexit.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #15 from LIU Hao --- Created attachment 58124 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58124=edit proposed patch v2 Update the patch. Did a quick test on i686-w64-mingw32 and seemed to solve the issue. Rebuilding everything now.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #14 from LIU Hao --- I suspect it's because that `get_atexit_fn_ptr_type` is shared by `atexit` and `__cxa_thread_atexit` but the destructors for them do not use the same calling convention .. So I should make a copy of it, as well as `atexit_fn_ptr_type_node`.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #13 from LIU Hao --- I am using a modified patch: ``` diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 4d6b2b98761..fbd9b4dac2e 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -25799,6 +25799,24 @@ ix86_bitint_type_info (int n, struct bitint_info *info) return true; } +/* Returns modified FUNCTION_TYPE for cdtor callabi. */ +tree +ix86_cxx_adjust_cdtor_callabi_fntype (tree fntype) +{ +fprintf(stderr, "TARGET_64BIT = %d\n", (bool) TARGET_64BIT); +fprintf(stderr, "TARGET_RTD = %d\n", (bool) TARGET_RTD); +fprintf(stderr, "ix86_function_type_abi = %d\n", ix86_function_type_abi (fntype)); + if (TARGET_64BIT + || TARGET_RTD + || ix86_function_type_abi (fntype) != MS_ABI) +return fntype; + /* For 32-bit MS ABI add thiscall attribute. */ + tree attribs = tree_cons (get_identifier ("thiscall"), NULL_TREE, + TYPE_ATTRIBUTES (fntype)); +fprintf(stderr, "__thiscall applied!\n"); + return build_type_attribute_variant (fntype, attribs); +} + /* Implement PUSH_ROUNDING. On 386, we have pushw instruction that decrements by exactly 2 no matter what the position was, there is no pushb. ``` There is no message when compiling the testcase: ``` E:\lh_mouse\Desktop>g++ test.cc -Wall -Wextra : error: conflicting declaration of C function 'int __cxxabiv1::__cxa_thread_atexit(void (*)(), void*, void*)' test.cc:3:16: note: previous declaration 'int __cxxabiv1::__cxa_thread_atexit(void (__attribute__((thiscall)) *)(void*), void*, void*)' 3 | extern "C" int __cxa_thread_atexit(void (__thiscall* dtor)(void*), void* obj, void* dso) noexcept; |^~~ ``` So I suspect this is a wrong place to look at.. ?
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #12 from LIU Hao --- testcase: ``` namespace __cxxabiv1 { extern "C" int __cxa_thread_atexit(void (__thiscall* dtor)(void*), void* obj, void* dso) noexcept; } struct nontrivial { nontrivial(); ~nontrivial(); }; void* get_data() { thread_local nontrivial nt; return } ``` ``` E:\lh_mouse\Desktop>g++ test.cc : error: conflicting declaration of C function 'int __cxxabiv1::__cxa_thread_atexit(void (*)(), void*, void*)' test.cc:3:18: note: previous declaration 'int __cxxabiv1::__cxa_thread_atexit(void (__attribute__((thiscall)) *)(void*), void*, void*)' 3 | extern "C" int __cxa_thread_atexit(void (__thiscall* dtor)(void*), void* obj, void* dso) noexcept; | ^~~ ```
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #11 from LIU Hao --- (In reply to LIU Hao from comment #10) > (In reply to Jakub Jelinek from comment #8) > > Created attachment 58123 [details] > > gcc15-pr114968.patch > > > > This is what I'd do, but completely untested... > > It does not solve the issue. > Wait, I can't reproduce the error with ``` namespace std { class type_info; } // namespace std extern "C" { int __cxa_at_quick_exit(void (__thiscall* dtor)(void*), void* obj, void* dso) noexcept; int __cxa_atexit(void (__thiscall* dtor)(void*), void* obj, void* dso) noexcept; int __cxa_thread_atexit(void (__thiscall* dtor)(void*), void* obj, void* dso) noexcept; void __cxa_throw(void* obj, std::type_info* type, void (__thiscall* dtor)(void*)); } // extern "C" ``` Probably there's something wrong in boost configuration. Investigating.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #10 from LIU Hao --- (In reply to Jakub Jelinek from comment #8) > Created attachment 58123 [details] > gcc15-pr114968.patch > > This is what I'd do, but completely untested... It does not solve the issue. Side note: Although I think `-mrtd` should mostly not be useful, the MSVC `/Gz` and Clang `-mrtd` function do not affect the calling convention of non-static member functions; they are always `__thiscall`, which means `this` goes in ECX and the others are passed on stack and popped by callee like `__stdcall`.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #9 from LIU Hao --- (In reply to Jakub Jelinek from comment #8) > Created attachment 58123 [details] > gcc15-pr114968.patch > > This is what I'd do, but completely untested... Thanks. I am gonna give it a run.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #8 from Jakub Jelinek --- Created attachment 58123 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58123=edit gcc15-pr114968.patch This is what I'd do, but completely untested...
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #7 from Jakub Jelinek --- (In reply to LIU Hao from comment #6) > I suspect this isn't correct. I am getting strange errors like 'ld exited > with code 5' not sure what could cause it (possibly also recent MSYS2 > updates): > > ``` > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc > index 2af026d255d..f5dce6a93bc 100644 > --- a/gcc/cp/decl.cc > +++ b/gcc/cp/decl.cc > @@ -9669,6 +9669,16 @@ get_atexit_fn_ptr_type (void) > >fn_type = build_function_type_list (void_type_node, > arg_type, NULL_TREE); > +#ifdef IX86_CALLCVT_THISCALL > + if (flag_use_cxa_atexit > + && !targetm.cxx.use_atexit_for_cxa_atexit ()) > +{ > + fn_type = copy_node (fn_type); > + TYPE_ATTRIBUTES (fn_type) = tree_cons ( > +get_identifier ("thiscall"), NULL_TREE, > +TYPE_ATTRIBUTES (fn_type)); > +} > +#endif >atexit_fn_ptr_type_node = build_pointer_type (fn_type); > } > > diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc > index f1ffda22fd3..00a8843fa2e 100644 > --- a/gcc/cp/except.cc > +++ b/gcc/cp/except.cc > @@ -648,6 +648,12 @@ build_throw (location_t loc, tree exp, tsubst_flags_t > complain) > { > tree tmp = build_function_type_list (void_type_node, > ptr_type_node, NULL_TREE); > +#ifdef IX86_CALLCVT_THISCALL > + tmp = copy_node (tmp); > + TYPE_ATTRIBUTES (tmp) = tree_cons ( > +get_identifier ("thiscall"), NULL_TREE, > +TYPE_ATTRIBUTES (tmp)); > +#endif > cleanup_type = build_pointer_type (tmp); > } > > > ``` Besides wrong formatting and the case that you need to build_variant_type (or build_distinct_type?, one needs to look at what will be normally done if you do: void (__attribute__((thiscall)) *fn) (void); ), you really can't do it like that. IX86_CALLCVT_THISCALL is defined on all x86_64/i?86 targets, so not limited to mingw 32-bit.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #6 from LIU Hao --- I suspect this isn't correct. I am getting strange errors like 'ld exited with code 5' not sure what could cause it (possibly also recent MSYS2 updates): ``` diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 2af026d255d..f5dce6a93bc 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -9669,6 +9669,16 @@ get_atexit_fn_ptr_type (void) fn_type = build_function_type_list (void_type_node, arg_type, NULL_TREE); +#ifdef IX86_CALLCVT_THISCALL + if (flag_use_cxa_atexit + && !targetm.cxx.use_atexit_for_cxa_atexit ()) +{ + fn_type = copy_node (fn_type); + TYPE_ATTRIBUTES (fn_type) = tree_cons ( +get_identifier ("thiscall"), NULL_TREE, +TYPE_ATTRIBUTES (fn_type)); +} +#endif atexit_fn_ptr_type_node = build_pointer_type (fn_type); } diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc index f1ffda22fd3..00a8843fa2e 100644 --- a/gcc/cp/except.cc +++ b/gcc/cp/except.cc @@ -648,6 +648,12 @@ build_throw (location_t loc, tree exp, tsubst_flags_t complain) { tree tmp = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE); +#ifdef IX86_CALLCVT_THISCALL + tmp = copy_node (tmp); + TYPE_ATTRIBUTES (tmp) = tree_cons ( +get_identifier ("thiscall"), NULL_TREE, +TYPE_ATTRIBUTES (tmp)); +#endif cleanup_type = build_pointer_type (tmp); } ```
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #5 from LIU Hao --- (In reply to LIU Hao from comment #4) > > (build_function_type_list returns a shared type, so if attributes are to be > > added, it needs to go on a variant of the type. > > Just saw this. So I would have to clone the tree..
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #4 from LIU Hao --- (In reply to Jakub Jelinek from comment #2) > Guess you need to add a target hook next to use_aeabi_atexit and > use_atexit_for_cxa_atexit which returns attributes that should be added to a > FUNCTION_TYPE constructed by get_atexit_fn_ptr_type > (build_function_type_list returns a shared type, so if attributes are to be > added, it needs to go on a variant of the type. > > On all but mingw ia32 it shouldn't add anything, and guess it shouldn't be > done if > !flag_use_cxa_atexit || !targetm.cxx.use_atexit_for_cxa_atexit () > A question is what to do about the __tcf_* cleanup functions that might be > sometimes created. > > Anyway, seems to be primarily mingw maintainer responsibility given that it > is the only target with such requirements. I think a quick and dirty solution should look like this? ``` diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 2af026d255d..311f1ca780b 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -9669,6 +9669,13 @@ get_atexit_fn_ptr_type (void) fn_type = build_function_type_list (void_type_node, arg_type, NULL_TREE); +#ifdef IX86_CALLCVT_THISCALL + if (flag_use_cxa_atexit + && !targetm.cxx.use_atexit_for_cxa_atexit ()) +TYPE_ATTRIBUTES (fn_type) = tree_cons ( + get_identifier ("thiscall"), NULL_TREE, + TYPE_ATTRIBUTES (fn_type)); +#endif atexit_fn_ptr_type_node = build_pointer_type (fn_type); } ```
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 --- Comment #3 from Jakub Jelinek --- Oh, the third argument type for __cxa_throw in cp/except.cc probably needs the same, so the target hook likely should be called similarly to the libstdc++ macro for that.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 Jakub Jelinek changed: What|Removed |Added CC||10walls at gmail dot com, ||jakub at gcc dot gnu.org, ||jason at gcc dot gnu.org --- Comment #2 from Jakub Jelinek --- Guess you need to add a target hook next to use_aeabi_atexit and use_atexit_for_cxa_atexit which returns attributes that should be added to a FUNCTION_TYPE constructed by get_atexit_fn_ptr_type (build_function_type_list returns a shared type, so if attributes are to be added, it needs to go on a variant of the type. On all but mingw ia32 it shouldn't add anything, and guess it shouldn't be done if !flag_use_cxa_atexit || !targetm.cxx.use_atexit_for_cxa_atexit () A question is what to do about the __tcf_* cleanup functions that might be sometimes created. Anyway, seems to be primarily mingw maintainer responsibility given that it is the only target with such requirements.
[Bug target/114968] [14/15 Regression] missing `__thiscall` attribute on builtin declaration of `__cxa_thread_atexit()`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114968 Richard Biener changed: What|Removed |Added Summary|missing `__thiscall`|[14/15 Regression] missing |attribute on builtin|`__thiscall` attribute on |declaration of |builtin declaration of |`__cxa_thread_atexit()` |`__cxa_thread_atexit()` Keywords||rejects-valid Target Milestone|--- |14.2