From patchwork Mon May 22 11:34:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 765373 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wWc5g6kDjz9s4q for ; Mon, 22 May 2017 21:35:02 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="a7193tJP"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=ngT/vcX9Npi39tFGQrEqEtV7Ha7LXdQmB4u4Blf+xw7Xf5dR3a +fsD+ANPoisw+mO+NFsM37/IY7evX2S66ShnUqfqm43MVzBfQ2pe/NNZGAsVG3FR /EyBJG4O5yXAv9JHX/Vg0Ju8IuaCLpY8FtpD5GkJDGg15WNBiQ9lKjlN0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=235WS8/i/4+PXosUV8Kf+zG5fcU=; b=a7193tJPyky4DG1Ygxtj 2I8qHd82ScH/XP74xgRgtPU/BjEXJsKTwkSVVsnE4E+zUoYVunnSpFQc+77QDw4D QhnbFcRtfytU3o4/D6BCvUS3IHU0DnqSYSJqaXn3CYlKCusWbmMAIFbaKZJFB9I9 NrVZAs+j3l0Fj/aWaL+E6BA= Received: (qmail 86966 invoked by alias); 22 May 2017 11:34:48 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 86934 invoked by uid 89); 22 May 2017 11:34:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-16.1 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=roots, ecf, ECF, whilst X-HELO: mail-yb0-f182.google.com Received: from mail-yb0-f182.google.com (HELO mail-yb0-f182.google.com) (209.85.213.182) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 22 May 2017 11:34:45 +0000 Received: by mail-yb0-f182.google.com with SMTP id 187so23201460ybg.0 for ; Mon, 22 May 2017 04:34:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:cc:from:subject:message-id:date :user-agent:mime-version:content-language; bh=PHsPkr2hjxB0dzc3I7XsQBquolai5LSl3HACNBkRqvQ=; b=UezHPt4YbugWurNwQCkD/Wv+Bky2QudkQFgGqjYQT2BbD/6bLyKYGg19ncHUb9czlU 4QUnwzL1GKSeRWPmJwD8L8lRh5thO+CVO/CqWhaUeYMFVwZE2Ni1PpCA/7+jR8jn/ADk cicimKHinuAWBB8/Al8p/cLoN6TcvfTd0HWKGV98kdDqiZ0WGWLSnxCVleCg0RGka7+D rLMYWz0fnjbetduNBlXSC+g6lVPQgYaKUiQzg0wZRPNCSfTUxEp+EYLa8hNH5kXQzvjh S67acd2xHKv9oWPMT74Hp3iJCbSx4ZNWq2BUGXAvAE6tmSBvLHkMOAz241zOabF1pO35 Vmig== X-Gm-Message-State: AODbwcDmUn/SEsoGpr/vxCvyxOeo7+zDh5rIq2IZ2b6d6ljdwz+AqoR3 3T8Pj2w1HYRNjw== X-Received: by 10.37.83.65 with SMTP id h62mr17661271ybb.92.1495452887395; Mon, 22 May 2017 04:34:47 -0700 (PDT) Received: from ?IPv6:2620:10d:c0a3:20fb:f6d0:5ac5:64cd:f102? ([2620:10d:c091:200::94]) by smtp.googlemail.com with ESMTPSA id i138sm7177195ywg.67.2017.05.22.04.34.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 22 May 2017 04:34:46 -0700 (PDT) To: GCC Patches Cc: Bernd Edlinger From: Nathan Sidwell Subject: [C++ PATCH] make eh fn nodes global trees Message-ID: Date: Mon, 22 May 2017 07:34:45 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.1.0 MIME-Version: 1.0 This patch neatens up the recent change in except.c to register GTY roots. I've made them all global trees. Whilst there I noticed except's declare_library_fn could be doing more work, rather than its callers repeat themselves. Also renamed a couple of global trees to be more mnemonic and consistent with these names. nathan 2017-05-22 Nathan Sidwell * cp-tree.h (CPTI_TERMINATE, CPTI_CALL_UNEXPECTED): Rename to ... (CPTI_TERMINATE_FN, CPTI_CALL_UNEXPECTED_FN): ... here. ( CPTI_GET_EXCEPTION_PTR_FN, CPTI_BEGIN_CATCH_FN, CPTI_END_CATCH_FN, CPTI_ALLOCATE_EXCEPTION_FN, CPTI_FREE_EXCEPTION_FN, CPTI_THROW_FN, CPTI_RETHROW_FN): New. (noexcept_deferred_spec): New. (terminate_node, call_unexpected_node): Rename to ... (terminate_fn, call_unexpected_fn): ... here. (get_exception_ptr_fn, begin_catch_fn, end_catch_fn, allocate_exception_fn, free_exception_fn, throw_fn, rethrow_fn): New. * except.c (fn1..fn5, throw_fn, rethrow_rn, spec): Delete. (init_exception_processing): Adjust. (declare_library_fn): Create and push the fns here. (do_get_exception_ptr, do_begin_catch, do_end_catch, do_allocate_exception_ptr, do_free_exception_ptr): Adjust declare_library_fn use. (unevaluated_noexcept_spec): Adjust. * cp-gimplify.c (genericize_eh_spec_block, gimplify_most_not_throw_expr): Adjust. Index: cp-gimplify.c =================================================================== --- cp-gimplify.c (revision 248326) +++ cp-gimplify.c (working copy) @@ -150,7 +150,7 @@ genericize_eh_spec_block (tree *stmt_p) { tree body = EH_SPEC_STMTS (*stmt_p); tree allowed = EH_SPEC_RAISES (*stmt_p); - tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ()); + tree failure = build_call_n (call_unexpected_fn, 1, build_exc_ptr ()); *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure); TREE_NO_WARNING (*stmt_p) = true; @@ -501,7 +501,7 @@ gimplify_must_not_throw_expr (tree *expr gimple *mnt; gimplify_and_add (body, &try_); - mnt = gimple_build_eh_must_not_throw (terminate_node); + mnt = gimple_build_eh_must_not_throw (terminate_fn); gimple_seq_add_stmt_without_update (&catch_, mnt); mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH); Index: cp-tree.h =================================================================== --- cp-tree.h (revision 248326) +++ cp-tree.h (working copy) @@ -153,8 +153,17 @@ enum cp_tree_index CPTI_EMPTY_EXCEPT_SPEC, CPTI_NOEXCEPT_TRUE_SPEC, CPTI_NOEXCEPT_FALSE_SPEC, - CPTI_TERMINATE, - CPTI_CALL_UNEXPECTED, + CPTI_NOEXCEPT_DEFERRED_SPEC, + + CPTI_TERMINATE_FN, + CPTI_CALL_UNEXPECTED_FN, + CPTI_GET_EXCEPTION_PTR_FN, + CPTI_BEGIN_CATCH_FN, + CPTI_END_CATCH_FN, + CPTI_ALLOCATE_EXCEPTION_FN, + CPTI_FREE_EXCEPTION_FN, + CPTI_THROW_FN, + CPTI_RETHROW_FN, CPTI_ATEXIT_FN_PTR_TYPE, CPTI_ATEXIT, CPTI_DSO_HANDLE, @@ -242,17 +251,24 @@ extern GTY(()) tree cp_global_trees[CPTI #define lang_name_c cp_global_trees[CPTI_LANG_NAME_C] #define lang_name_cplusplus cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS] -/* Exception specifiers used for throw(), noexcept(true) and - noexcept(false). We rely on these being uncloned. */ +/* Exception specifiers used for throw(), noexcept(true), + noexcept(false) and deferred noexcept. We rely on these being + uncloned. */ #define empty_except_spec cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC] #define noexcept_true_spec cp_global_trees[CPTI_NOEXCEPT_TRUE_SPEC] #define noexcept_false_spec cp_global_trees[CPTI_NOEXCEPT_FALSE_SPEC] +#define noexcept_deferred_spec cp_global_trees[CPTI_NOEXCEPT_DEFERRED_SPEC] -/* The declaration for `std::terminate'. */ -#define terminate_node cp_global_trees[CPTI_TERMINATE] - -/* The declaration for "__cxa_call_unexpected". */ -#define call_unexpected_node cp_global_trees[CPTI_CALL_UNEXPECTED] +/* Exception handling function declarations. */ +#define terminate_fn cp_global_trees[CPTI_TERMINATE_FN] +#define call_unexpected_fn cp_global_trees[CPTI_CALL_UNEXPECTED_FN] +#define get_exception_ptr_fn cp_global_trees[CPTI_GET_EXCEPTION_PTR_FN] +#define begin_catch_fn cp_global_trees[CPTI_BEGIN_CATCH_FN] +#define end_catch_fn cp_global_trees[CPTI_END_CATCH_FN] +#define allocate_exception_fn cp_global_trees[CPTI_ALLOCATE_EXCEPTION_FN] +#define free_exception_fn cp_global_trees[CPTI_FREE_EXCEPTION_FN] +#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). */ Index: except.c =================================================================== --- except.c (revision 248326) +++ except.c (working copy) @@ -42,15 +42,6 @@ static int complete_ptr_ref_or_void_ptr_ static bool is_admissible_throw_operand_or_catch_parameter (tree, bool); static int can_convert_eh (tree, tree); -static GTY(()) tree fn1; -static GTY(()) tree fn2; -static GTY(()) tree fn3; -static GTY(()) tree fn4; -static GTY(()) tree fn5; -static GTY(()) tree throw_fn; -static GTY(()) tree rethrow_fn; -static GTY(()) tree spec; - /* Sets up all the global eh stuff that needs to be initialized at the start of compilation. */ @@ -62,15 +53,15 @@ init_exception_processing (void) /* void std::terminate (); */ push_namespace (std_identifier); tmp = build_function_type_list (void_type_node, NULL_TREE); - terminate_node = build_cp_library_fn_ptr ("terminate", tmp, + terminate_fn = build_cp_library_fn_ptr ("terminate", tmp, ECF_NOTHROW | ECF_NORETURN); - TREE_THIS_VOLATILE (terminate_node) = 1; - TREE_NOTHROW (terminate_node) = 1; + TREE_THIS_VOLATILE (terminate_fn) = 1; + TREE_NOTHROW (terminate_fn) = 1; pop_namespace (); /* void __cxa_call_unexpected(void *); */ tmp = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE); - call_unexpected_node + call_unexpected_fn = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp); } @@ -84,7 +75,7 @@ cp_protect_cleanup_actions (void) When the destruction of an object during stack unwinding exits using an exception ... void terminate(); is called. */ - return terminate_node; + return terminate_fn; } static tree @@ -140,21 +131,39 @@ build_exc_ptr (void) 1, integer_zero_node); } -/* Declare a function NAME, returning RETURN_TYPE, taking a single - parameter PARM_TYPE, with an empty exception specification. +/* Find or declare a function NAME, returning RTYPE, taking a single + parameter PTYPE, with an empty exception specification. ECF are the + library fn flags. If TM_ECF is non-zero, also find or create a + transaction variant and record it as a replacement, when flag_tm is + in effect. Note that the C++ ABI document does not have a throw-specifier on the routines declared below via this function. The declarations are consistent with the actual implementations in libsupc++. */ static tree -declare_library_fn (tree name, tree return_type, tree parm_type, int ecf_flags) +declare_library_fn (const char *name, tree rtype, tree ptype, + int ecf, int tm_ecf) { - return push_library_fn (name, build_function_type_list (return_type, - parm_type, - NULL_TREE), - empty_except_spec, - ecf_flags); + tree ident = get_identifier (name); + tree res = IDENTIFIER_GLOBAL_VALUE (ident); + if (!res) + { + tree type = build_function_type_list (rtype, ptype, NULL_TREE); + tree except = ecf & ECF_NOTHROW ? empty_except_spec : NULL_TREE; + res = push_library_fn (ident, type, except, ecf); + if (tm_ecf && flag_tm) + { + char *tm_name = concat ("_ITM_", name + 2, NULL_TREE); + tree tm_ident = get_identifier (tm_name); + free (tm_name); + tree tm_fn = IDENTIFIER_GLOBAL_VALUE (tm_ident); + if (!tm_fn) + tm_fn = push_library_fn (tm_ident, type, except, ecf | tm_ecf); + record_tm_replacement (res, tm_fn); + } + } + return res; } /* Build up a call to __cxa_get_exception_ptr so that we can build a @@ -163,18 +172,16 @@ declare_library_fn (tree name, tree retu static tree do_get_exception_ptr (void) { - if (!fn1) - { - tree name = get_identifier ("__cxa_get_exception_ptr"); - fn1 = IDENTIFIER_GLOBAL_VALUE (name); - if (!fn1) - /* Declare void* __cxa_get_exception_ptr (void *) throw(). */ - fn1 = declare_library_fn - (name, ptr_type_node, ptr_type_node, - ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE); - } + if (!get_exception_ptr_fn) + /* Declare void* __cxa_get_exception_ptr (void *) throw(). */ + get_exception_ptr_fn + = declare_library_fn ("__cxa_get_exception_ptr", + ptr_type_node, ptr_type_node, + ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE, + 0); - return cp_build_function_call_nary (fn1, tf_warning_or_error, + return cp_build_function_call_nary (get_exception_ptr_fn, + tf_warning_or_error, build_exc_ptr (), NULL_TREE); } @@ -184,31 +191,14 @@ do_get_exception_ptr (void) static tree do_begin_catch (void) { - if (!fn2) - { - tree name = get_identifier ("__cxa_begin_catch"); - fn2 = IDENTIFIER_GLOBAL_VALUE (name); - if (!fn2) - { - /* Declare void* __cxa_begin_catch (void *) throw(). */ - fn2 = declare_library_fn - (name, ptr_type_node, ptr_type_node, ECF_NOTHROW); + if (!begin_catch_fn) + /* Declare void* __cxa_begin_catch (void *) throw(). */ + begin_catch_fn + = declare_library_fn ("__cxa_begin_catch", + ptr_type_node, ptr_type_node, ECF_NOTHROW, + ECF_TM_PURE); - /* Create its transactional-memory equivalent. */ - if (flag_tm) - { - tree itm_name = get_identifier ("_ITM_cxa_begin_catch"); - tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name); - if (!itm_fn) - itm_fn = declare_library_fn - (itm_name, ptr_type_node, ptr_type_node, - ECF_NOTHROW | ECF_TM_PURE); - record_tm_replacement (fn2, itm_fn); - } - } - } - - return cp_build_function_call_nary (fn2, tf_warning_or_error, + return cp_build_function_call_nary (begin_catch_fn, tf_warning_or_error, build_exc_ptr (), NULL_TREE); } @@ -236,30 +226,15 @@ dtor_nothrow (tree type) static tree do_end_catch (tree type) { - if (!fn3) - { - tree name = get_identifier ("__cxa_end_catch"); - fn3 = IDENTIFIER_GLOBAL_VALUE (name); - if (!fn3) - { - /* Declare void __cxa_end_catch (). - This can throw if the destructor for the exception throws. */ - fn3 = push_void_library_fn (name, void_list_node, 0); - - /* Create its transactional-memory equivalent. */ - if (flag_tm) - { - tree itm_name = get_identifier ("_ITM_cxa_end_catch"); - tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name); - if (!itm_fn) - itm_fn = push_void_library_fn - (itm_name, void_list_node, ECF_TM_PURE); - record_tm_replacement (fn3, itm_fn); - } - } - } + if (!end_catch_fn) + /* Declare void __cxa_end_catch (). + This can throw if the destructor for the exception throws. */ + end_catch_fn + = declare_library_fn ("__cxa_end_catch", void_type_node, + NULL_TREE, 0, ECF_TM_PURE); - tree cleanup = cp_build_function_call_vec (fn3, NULL, tf_warning_or_error); + tree cleanup = cp_build_function_call_vec (end_catch_fn, + NULL, tf_warning_or_error); TREE_NOTHROW (cleanup) = dtor_nothrow (type); return cleanup; @@ -519,30 +494,15 @@ finish_eh_spec_block (tree raw_raises, t static tree do_allocate_exception (tree type) { - if (!fn4) - { - tree name = get_identifier ("__cxa_allocate_exception"); - fn4 = IDENTIFIER_GLOBAL_VALUE (name); - if (!fn4) - { - /* Declare void *__cxa_allocate_exception(size_t) throw(). */ - fn4 = declare_library_fn (name, ptr_type_node, size_type_node, - ECF_NOTHROW | ECF_MALLOC); + if (!allocate_exception_fn) + /* Declare void *__cxa_allocate_exception(size_t) throw(). */ + allocate_exception_fn + = declare_library_fn ("__cxa_allocate_exception", + ptr_type_node, size_type_node, + ECF_NOTHROW | ECF_MALLOC, ECF_TM_PURE); - if (flag_tm) - { - tree itm_name = get_identifier ("_ITM_cxa_allocate_exception"); - tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name); - if (!itm_fn) - itm_fn = declare_library_fn - (itm_name, ptr_type_node, size_type_node, - ECF_NOTHROW | ECF_MALLOC | ECF_TM_PURE); - record_tm_replacement (fn4, itm_fn); - } - } - } - - return cp_build_function_call_nary (fn4, tf_warning_or_error, + return cp_build_function_call_nary (allocate_exception_fn, + tf_warning_or_error, size_in_bytes (type), NULL_TREE); } @@ -552,30 +512,15 @@ do_allocate_exception (tree type) static tree do_free_exception (tree ptr) { - if (!fn5) - { - tree name = get_identifier ("__cxa_free_exception"); - fn5 = IDENTIFIER_GLOBAL_VALUE (name); - if (!fn5) - { - /* Declare void __cxa_free_exception (void *) throw(). */ - fn5 = declare_library_fn (name, void_type_node, ptr_type_node, - ECF_NOTHROW | ECF_LEAF); - - if (flag_tm) - { - tree itm_name = get_identifier ("_ITM_cxa_free_exception"); - tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name); - if (!itm_fn) - itm_fn = declare_library_fn - (itm_name, void_type_node, ptr_type_node, - ECF_NOTHROW | ECF_LEAF | ECF_TM_PURE); - record_tm_replacement (fn5, itm_fn); - } - } - } + if (!free_exception_fn) + /* Declare void __cxa_free_exception (void *) throw(). */ + free_exception_fn + = declare_library_fn ("__cxa_free_exception", + void_type_node, ptr_type_node, + ECF_NOTHROW | ECF_LEAF, ECF_TM_PURE); - return cp_build_function_call_nary (fn5, tf_warning_or_error, ptr, NULL_TREE); + return cp_build_function_call_nary (free_exception_fn, + tf_warning_or_error, ptr, NULL_TREE); } /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR. @@ -1257,9 +1202,10 @@ build_noexcept_spec (tree expr, int comp tree unevaluated_noexcept_spec (void) { - if (spec == NULL_TREE) - spec = build_noexcept_spec (make_node (DEFERRED_NOEXCEPT), tf_none); - return spec; + if (!noexcept_deferred_spec) + noexcept_deferred_spec + = build_noexcept_spec (make_node (DEFERRED_NOEXCEPT), tf_none); + return noexcept_deferred_spec; } /* Returns a TRY_CATCH_EXPR that will put TRY_LIST and CATCH_LIST in the