From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 6BB0C3858D39 for ; Thu, 9 May 2024 18:46:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6BB0C3858D39 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6BB0C3858D39 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715280413; cv=none; b=cSCelUipZlyxD7TSoIVsIZQQmfdSsgnknp+dzGYnlK9MJ/44Pp+pFeAPsqG0dX7CQWZwMoiAjVP+bhM3IGJSye1DW1hNKciSOGeGBe0Eb8Bt8LotZDRS9kCt6QMmIiCq6fA2KDXBKkKG3yMiTu5oIH7nxcbnmllZhWhhBsnUiSw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715280413; c=relaxed/simple; bh=pASYibDu7cDr5KCSXSGzoFtZyuAb79cn94HSDvPXec8=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=J1P9ZvzZ6xY5qvG+PJFGFflhInQCauI2S4NtR8J/BKWYx+to68VjNDW2wLITZU5Yh0o9UbE30i1XBnQ8pVlEKh95w3Ap+e4keK+V7i1WbH5+CaHnN6KuGTl7aL43e3peYkn7JJbqLrhx3P71RLpCZ2I6EelMUFYypo1sOzQuE7M= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715280411; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references; bh=fzMw6go0t8LO9JqDmcgK9AOd5ijp+/hUSXsIamW/BIQ=; b=BpzxItE8npaNx4BAK+ZriiNliH764KBUmyxp0ZsqGEn3vh8ON9p9wCFbN3bHnqNNipC51O OxQxl2O0fqqD0jmG/3QVC/mnfsvqyrBuWpEa3ZGBWT3an6ScnYCE1+pGhmJOuwIvY+2agy 0dpZ/ohkv4wdi11J7tngI1uPSwBtL1o= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-618-Vi6Fe5CXPu25TJNkfSviIQ-1; Thu, 09 May 2024 14:46:31 -0400 X-MC-Unique: Vi6Fe5CXPu25TJNkfSviIQ-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 066F529AA39C for ; Thu, 9 May 2024 18:46:31 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.224.64]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A2AF151902F; Thu, 9 May 2024 18:46:30 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 449IkTfN505314 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 9 May 2024 20:46:29 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 449IkSO4505313; Thu, 9 May 2024 20:46:28 +0200 Date: Thu, 9 May 2024 20:46:28 +0200 From: Jakub Jelinek To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] c++, mingw, v2: Fix up types of dtor hooks to __cxa_{,thread_}atexit/__cxa_throw on mingw ia32 [PR114968] Message-ID: Reply-To: Jakub Jelinek References: <5cdeb0ad-d54f-4812-a344-fb3981dddca7@redhat.com> MIME-Version: 1.0 In-Reply-To: <5cdeb0ad-d54f-4812-a344-fb3981dddca7@redhat.com> X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.10 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Thu, May 09, 2024 at 01:05:59PM -0400, Jason Merrill wrote: > I think I'd rather pass ob_parm to start_cleanup_fn, where it can also > replace the flag_use_cxa_atexit check in that function. Good idea, changed in the following patch. > > @@ -9998,7 +10004,8 @@ register_dtor_fn (tree decl) > > { > > /* We must convert CLEANUP to the type that "__cxa_atexit" > > expects. */ > > - cleanup = build_nop (get_atexit_fn_ptr_type (), cleanup); > > + cleanup = build_nop (ob_parm ? get_cxa_atexit_fn_ptr_type () > > + : get_atexit_fn_ptr_type (), cleanup); > > If we're (now) using the correct type to build the cleanup fn, this > conversion should be unnecessary. This is the use_dtor case, where cleanup will have METHOD_TYPE, so I think we need to cast. But, we can cast always to get_cxa_atexit_fn_ptr_type () type, because this is in use_dtor guarded code and use_dtor is ob_parm && CLASS_TYPE_P (type), so when use_dtor is true, ob_parm is also true. Ok for trunk if it passes another bootstrap/regtest? 2024-05-09 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 (). --- gcc/target.def.jj 2024-05-09 10:30:54.926503473 +0200 +++ gcc/target.def 2024-05-09 20:27:16.294780780 +0200 @@ -6498,7 +6498,7 @@ is in effect. The default is to return hook_bool_void_false) /* Returns true if target may use atexit in the same manner as - __cxa_atexit to register static destructors. */ + __cxa_atexit to register static destructors. */ DEFHOOK (use_atexit_for_cxa_atexit, "This hook returns true if the target @code{atexit} function can be used\n\ @@ -6509,6 +6509,17 @@ unloaded. The default is to return false bool, (void), hook_bool_void_false) +/* Returns modified FUNCTION_TYPE for cdtor callabi. */ +DEFHOOK +(adjust_cdtor_callabi_fntype, + "This hook returns a possibly modified @code{FUNCTION_TYPE} for arguments\n\ +to @code{__cxa_atexit}, @code{__cxa_thread_atexit} or @code{__cxa_throw}\n\ +function pointers. ABIs like mingw32 require special attributes to be added\n\ +to function types pointed to by arguments of these functions.\n\ +The default is to return the passed argument unmodified.", + tree, (tree fntype), + default_cxx_adjust_cdtor_callabi_fntype) + DEFHOOK (adjust_class_at_definition, "@var{type} is a C++ class (i.e., RECORD_TYPE or UNION_TYPE) that has just\n\ --- gcc/targhooks.h.jj 2024-05-09 10:30:54.941503269 +0200 +++ gcc/targhooks.h 2024-05-09 20:27:16.315780505 +0200 @@ -65,6 +65,7 @@ extern machine_mode default_mode_for_suf extern tree default_cxx_guard_type (void); extern tree default_cxx_get_cookie_size (tree); +extern tree default_cxx_adjust_cdtor_callabi_fntype (tree); extern bool hook_pass_by_reference_must_pass_in_stack (cumulative_args_t, const function_arg_info &); --- gcc/targhooks.cc.jj 2024-05-09 10:30:54.927503459 +0200 +++ gcc/targhooks.cc 2024-05-09 20:27:16.338780204 +0200 @@ -329,6 +329,14 @@ default_cxx_get_cookie_size (tree type) return cookie_size; } +/* Returns modified FUNCTION_TYPE for cdtor callabi. */ + +tree +default_cxx_adjust_cdtor_callabi_fntype (tree fntype) +{ + return fntype; +} + /* Return true if a parameter must be passed by reference. This version of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */ --- gcc/doc/tm.texi.in.jj 2024-05-09 10:30:54.897503866 +0200 +++ gcc/doc/tm.texi.in 2024-05-09 20:27:16.355779981 +0200 @@ -7223,6 +7223,8 @@ floating-point support; they are not inc @hook TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT +@hook TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE + @hook TARGET_CXX_ADJUST_CLASS_AT_DEFINITION @hook TARGET_CXX_DECL_MANGLING_CONTEXT --- gcc/doc/tm.texi.jj 2024-05-09 10:30:54.862504342 +0200 +++ gcc/doc/tm.texi 2024-05-09 20:27:16.368779810 +0200 @@ -11117,6 +11117,14 @@ shared libraries are run in the correct unloaded. The default is to return false. @end deftypefn +@deftypefn {Target Hook} tree TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE (tree @var{fntype}) +This hook returns a possibly modified @code{FUNCTION_TYPE} for arguments +to @code{__cxa_atexit}, @code{__cxa_thread_atexit} or @code{__cxa_throw} +function pointers. ABIs like mingw32 require special attributes to be added +to function types pointed to by arguments of these functions. +The default is to return the passed argument unmodified. +@end deftypefn + @deftypefn {Target Hook} void TARGET_CXX_ADJUST_CLASS_AT_DEFINITION (tree @var{type}) @var{type} is a C++ class (i.e., RECORD_TYPE or UNION_TYPE) that has just been defined. Use this hook to make adjustments to the class (eg, tweak --- gcc/config/i386/i386.cc.jj 2024-05-09 10:30:58.508454809 +0200 +++ gcc/config/i386/i386.cc 2024-05-09 20:27:16.392779496 +0200 @@ -25800,6 +25800,20 @@ ix86_bitint_type_info (int n, struct bit return true; } +/* Returns modified FUNCTION_TYPE for cdtor callabi. */ +tree +ix86_cxx_adjust_cdtor_callabi_fntype (tree 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)); + 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. @@ -26411,6 +26425,8 @@ static const scoped_attribute_specs *con #define TARGET_C_EXCESS_PRECISION ix86_get_excess_precision #undef TARGET_C_BITINT_TYPE_INFO #define TARGET_C_BITINT_TYPE_INFO ix86_bitint_type_info +#undef TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE +#define TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE ix86_cxx_adjust_cdtor_callabi_fntype #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true #undef TARGET_PUSH_ARGUMENT --- gcc/cp/cp-tree.h.jj 2024-05-09 20:26:12.619615230 +0200 +++ gcc/cp/cp-tree.h 2024-05-09 20:27:16.395779457 +0200 @@ -368,8 +368,7 @@ extern GTY(()) tree cp_global_trees[CPTI #define throw_fn cp_global_trees[CPTI_THROW_FN] #define rethrow_fn cp_global_trees[CPTI_RETHROW_FN] -/* The type of the function-pointer argument to "__cxa_atexit" (or - "std::atexit", if "__cxa_atexit" is not being used). */ +/* The type of the function-pointer argument to "std::atexit". */ #define atexit_fn_ptr_type_node cp_global_trees[CPTI_ATEXIT_FN_PTR_TYPE] /* A pointer to `std::atexit'. */ @@ -384,7 +383,8 @@ extern GTY(()) tree cp_global_trees[CPTI /* The declaration of the dynamic_cast runtime. */ #define dynamic_cast_node cp_global_trees[CPTI_DCAST] -/* The type of a destructor. */ +/* The type of a destructor, passed to __cxa_atexit, __cxa_thread_atexit + or __cxa_throw. */ #define cleanup_type cp_global_trees[CPTI_CLEANUP_TYPE] /* The type of the vtt parameter passed to subobject constructors and @@ -7067,6 +7067,7 @@ extern tree check_default_argument (tre extern int wrapup_namespace_globals (); extern tree create_implicit_typedef (tree, tree); extern int local_variable_p (const_tree); +extern tree get_cxa_atexit_fn_ptr_type (); extern tree register_dtor_fn (tree); extern tmpl_spec_kind current_tmpl_spec_kind (int); extern tree cxx_builtin_function (tree decl); --- gcc/cp/decl.cc.jj 2024-05-09 20:26:12.670614561 +0200 +++ gcc/cp/decl.cc 2024-05-09 20:34:08.556378168 +0200 @@ -93,7 +93,7 @@ static void record_key_method_defined (t static tree create_array_type_for_decl (tree, tree, tree, location_t); static tree get_atexit_node (void); static tree get_dso_handle_node (void); -static tree start_cleanup_fn (void); +static tree start_cleanup_fn (bool); static void end_cleanup_fn (void); static tree cp_make_fname_decl (location_t, tree, int); static void initialize_predefined_identifiers (void); @@ -9678,34 +9678,39 @@ declare_global_var (tree name, tree type return decl; } -/* Returns the type for the argument to "__cxa_atexit" (or "atexit", - if "__cxa_atexit" is not being used) corresponding to the function +/* Returns the type for the argument to "atexit" corresponding to the function to be called when the program exits. */ static tree -get_atexit_fn_ptr_type (void) +get_atexit_fn_ptr_type () { - tree fn_type; - if (!atexit_fn_ptr_type_node) { - tree arg_type; - if (flag_use_cxa_atexit - && !targetm.cxx.use_atexit_for_cxa_atexit ()) - /* The parameter to "__cxa_atexit" is "void (*)(void *)". */ - arg_type = ptr_type_node; - else - /* The parameter to "atexit" is "void (*)(void)". */ - arg_type = NULL_TREE; - - fn_type = build_function_type_list (void_type_node, - arg_type, NULL_TREE); + tree fn_type = build_function_type_list (void_type_node, NULL_TREE); atexit_fn_ptr_type_node = build_pointer_type (fn_type); } return atexit_fn_ptr_type_node; } +/* Returns the type for the argument to "__cxa_atexit", "__cxa_thread_atexit" + or "__cxa_throw" corresponding to the destructor to be called when the + program exits. */ + +tree +get_cxa_atexit_fn_ptr_type () +{ + if (!cleanup_type) + { + tree fntype = build_function_type_list (void_type_node, + ptr_type_node, NULL_TREE); + fntype = targetm.cxx.adjust_cdtor_callabi_fntype (fntype); + cleanup_type = build_pointer_type (fntype); + } + + return cleanup_type; +} + /* Returns a pointer to the `atexit' function. Note that if FLAG_USE_CXA_ATEXIT is nonzero, then this will actually be the new `__cxa_atexit' function specified in the IA64 C++ ABI. */ @@ -9736,7 +9741,7 @@ get_atexit_node (void) use_aeabi_atexit = targetm.cxx.use_aeabi_atexit (); /* First, build the pointer-to-function type for the first argument. */ - fn_ptr_type = get_atexit_fn_ptr_type (); + fn_ptr_type = get_cxa_atexit_fn_ptr_type (); /* Then, build the rest of the argument types. */ argtype2 = ptr_type_node; if (use_aeabi_atexit) @@ -9819,7 +9824,7 @@ get_thread_atexit_node (void) int __cxa_thread_atexit (void (*)(void *), void *, void *) */ tree fn_type = build_function_type_list (integer_type_node, - get_atexit_fn_ptr_type (), + get_cxa_atexit_fn_ptr_type (), ptr_type_node, ptr_type_node, NULL_TREE); @@ -9861,12 +9866,13 @@ get_dso_handle_node (void) } /* Begin a new function with internal linkage whose job will be simply - to destroy some particular variable. */ + to destroy some particular variable. OB_PARM is true if object pointer + is passed to the cleanup function, otherwise no argument is passed. */ static GTY(()) int start_cleanup_cnt; static tree -start_cleanup_fn (void) +start_cleanup_fn (bool ob_parm) { char name[32]; @@ -9877,8 +9883,9 @@ start_cleanup_fn (void) /* Build the name of the function. */ sprintf (name, "__tcf_%d", start_cleanup_cnt++); + tree fntype = TREE_TYPE (ob_parm ? get_cxa_atexit_fn_ptr_type () + : get_atexit_fn_ptr_type ()); /* Build the function declaration. */ - tree fntype = TREE_TYPE (get_atexit_fn_ptr_type ()); tree fndecl = build_lang_decl (FUNCTION_DECL, get_identifier (name), fntype); DECL_CONTEXT (fndecl) = FROB_CONTEXT (current_namespace); /* It's a function with internal linkage, generated by the @@ -9891,7 +9898,7 @@ start_cleanup_fn (void) emissions this way. */ DECL_DECLARED_INLINE_P (fndecl) = 1; DECL_INTERFACE_KNOWN (fndecl) = 1; - if (flag_use_cxa_atexit && !targetm.cxx.use_atexit_for_cxa_atexit ()) + if (ob_parm) { /* Build the parameter. */ tree parmdecl = cp_build_parm_decl (fndecl, NULL_TREE, ptr_type_node); @@ -9968,8 +9975,8 @@ register_dtor_fn (tree decl) build_cleanup (decl); /* Now start the function. */ - cleanup = start_cleanup_fn (); - + cleanup = start_cleanup_fn (ob_parm); + /* Now, recompute the cleanup. It may contain SAVE_EXPRs that refer to the original function, rather than the anonymous one. That will make the back end think that nested functions are in use, @@ -9998,7 +10005,7 @@ register_dtor_fn (tree decl) { /* We must convert CLEANUP to the type that "__cxa_atexit" expects. */ - cleanup = build_nop (get_atexit_fn_ptr_type (), cleanup); + cleanup = build_nop (get_cxa_atexit_fn_ptr_type (), cleanup); /* "__cxa_atexit" will pass the address of DECL to the cleanup function. */ mark_used (decl); --- gcc/cp/except.cc.jj 2024-05-09 10:30:54.821504899 +0200 +++ gcc/cp/except.cc 2024-05-09 20:27:16.412779234 +0200 @@ -645,11 +645,7 @@ build_throw (location_t loc, tree exp, t /* The CLEANUP_TYPE is the internal type of a destructor. */ if (!cleanup_type) - { - tree tmp = build_function_type_list (void_type_node, - ptr_type_node, NULL_TREE); - cleanup_type = build_pointer_type (tmp); - } + cleanup_type = get_cxa_atexit_fn_ptr_type (); if (!throw_fn) { Jakub