This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ patch] Set attributes for C++ runtime library calls


On Thu, Aug 22, 2013 at 8:19 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
>
> Hi,
> this patch started as a work to make cxa_pure_virtual as noreturn.  This
> is good for middle-end to figure out that it should not care about
> devirtualizing to it and it should devirtualize speculative where there
> is only one variant.  I ended up switching the function building
> stuff to use ecf_flags that is handy to set other attributes, too.
>
> I tried to go across all functions build and assign them correct attributes.
> I expecitely listed them all in changelog to make it easier to double
> check: I am not expert on C++ runtime.
>
> I have three questions:
>
>  - I tried to track functions that lead to terminate() and not mark them
>    as ECF_LEAF.  This is because user can set handler.  If the handler
>    can resonably expect the static vars defined in its unit to be
>    in the final form, we can not consider it ECF_LEAF.
>    Perhaps there are cases where terminate() is called only for programs
>    already after undefined effect?
>  - I would like to recall issue if we can make NEW_EXPR annotated with
>    MALLOC attribute.  Without it, it is basically impossible to track
>    any dynamically allocated objects in the middle-end

operator new is replaceable by user program.

>  - Is do_end_catch nothrow? It does not seem to be declared so in libsupc++
>
> Bootstrapped/regtested x86_64-linux, OK?
>
>         * class.c (build_vtbl_initializer): Make __cxa_deleted_virtual
>         ECF_NORETURN
>         * cp-tree.h (build_library_fn_ptr, build_cp_library_fn_ptr,
>         push_library_fn, push_void_library_fn): Update prototype.
>         * decl.c (build_library_fn_1): Remove.
>         (push_cp_library_fn, build_cp_library_fn): Update to take ECF flags.
>         (cxx_init_decl_processing): Update; global_delete_fndecl is ECF_NOTROW;
>         __cxa_pure_virtual is ECF_NORETURN | ECF_NORETURN.
>         (build_library_fn_1): Add ecf_flags argument; rename to ...
>         (build_library_fn): ... this one.
>         (build_cp_library_fn): Take ecf_flags; do not copy NOTHROW flag.
>         (build_library_fn_ptr): Take ecf_flags.
>         (build_cp_library_fn_ptr): Likewise.
>         (push_library_fn): Likewise.
>         (push_cp_library_fn): Likewise.
>         (push_void_library_fn): Likewise.
>         (push_throw_library_fn): All throws are ECF_NORETURN.
>         (__cxa_atexit, __cxa_thread_atexit): Add ECF_LEAF | ECF_NOTHROW attributes.
>         (expand_static_init): __cxa_guard_acquire, __cxa_guard_release,
>         __cxa_guard_abort are ECF_NOTHROW | ECF_LEAF.
>         * except.c (init_exception_processing): terminate is
>         ECF_NOTHROW | ECF_NORETURN.
>         (declare_nothrow_library_fn): Add ecf_flags parameter.
>         (__cxa_get_exception_ptr): Is ECF_NOTHROW | ECF_PURE | ECF_LEAF |
>         ECF_TM_PURE.
>         (do_begin_catch): cxa_begin_catch and _ITM_cxa_begin_catch
>         are ECF_NOTHROW.
>         (do_end_catch): __cxa_end_catch and _ITM_cxa_end_catch is
>         nothing.
>         (do_allocate_exception): _cxa_allocate_exception
>         and _ITM_cxa_allocate_exception are ECF_NOTHROW | ECF_MALLOC
>         (do_free_exception): __cxa_free_exception is
>         ECF_NOTHROW | ECF_LEAF.
>         * rtti.c (build_dynamic_cast_1): __dynamic_cast
>         is ECF_LEAF | ECF_PURE | ECF_NOTHROW.
>
> Index: cp/class.c
> ===================================================================
> *** cp/class.c  (revision 201910)
> --- cp/class.c  (working copy)
> *************** build_vtbl_initializer (tree binfo,
> *** 8857,8863 ****
>               if (!get_global_value_if_present (fn, &fn))
>                 fn = push_library_fn (fn, (build_function_type_list
>                                            (void_type_node, NULL_TREE)),
> !                                     NULL_TREE);
>               if (!TARGET_VTABLE_USES_DESCRIPTORS)
>                 init = fold_convert (vfunc_ptr_type_node,
>                                      build_fold_addr_expr (fn));
> --- 8857,8863 ----
>               if (!get_global_value_if_present (fn, &fn))
>                 fn = push_library_fn (fn, (build_function_type_list
>                                            (void_type_node, NULL_TREE)),
> !                                     NULL_TREE, ECF_NORETURN);
>               if (!TARGET_VTABLE_USES_DESCRIPTORS)
>                 init = fold_convert (vfunc_ptr_type_node,
>                                      build_fold_addr_expr (fn));
> Index: cp/cp-tree.h
> ===================================================================
> *** cp/cp-tree.h        (revision 201910)
> --- cp/cp-tree.h        (working copy)
> *************** extern void check_goto                          (tree);
> *** 5173,5182 ****
>   extern bool check_omp_return                  (void);
>   extern tree make_typename_type                        (tree, tree, enum tag_types, tsubst_flags_t);
>   extern tree make_unbound_class_template               (tree, tree, tree, tsubst_flags_t);
> ! extern tree build_library_fn_ptr              (const char *, tree);
> ! extern tree build_cp_library_fn_ptr           (const char *, tree);
> ! extern tree push_library_fn                   (tree, tree, tree);
> ! extern tree push_void_library_fn              (tree, tree);
>   extern tree push_throw_library_fn             (tree, tree);
>   extern void warn_misplaced_attr_for_class_type  (source_location location,
>                                                  tree class_type);
> --- 5169,5178 ----
>   extern bool check_omp_return                  (void);
>   extern tree make_typename_type                        (tree, tree, enum tag_types, tsubst_flags_t);
>   extern tree make_unbound_class_template               (tree, tree, tree, tsubst_flags_t);
> ! extern tree build_library_fn_ptr              (const char *, tree, int);
> ! extern tree build_cp_library_fn_ptr           (const char *, tree, int);
> ! extern tree push_library_fn                   (tree, tree, tree, int);
> ! extern tree push_void_library_fn              (tree, tree, int);
>   extern tree push_throw_library_fn             (tree, tree);
>   extern void warn_misplaced_attr_for_class_type  (source_location location,
>                                                  tree class_type);
> Index: cp/decl.c
> ===================================================================
> *** cp/decl.c   (revision 201910)
> --- cp/decl.c   (working copy)
> *************** static tree grokvardecl (tree, tree, con
> *** 75,81 ****
>   static int check_static_variable_definition (tree, tree);
>   static void record_unknown_type (tree, const char *);
>   static tree builtin_function_1 (tree, tree, bool);
> - static tree build_library_fn_1 (tree, enum tree_code, tree);
>   static int member_function_or_else (tree, tree, enum overload_flags);
>   static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int,
>                             int);
> --- 75,80 ----
> *************** static tree cp_make_fname_decl (location
> *** 107,114 ****
>   static void initialize_predefined_identifiers (void);
>   static tree check_special_function_return_type
>         (special_function_kind, tree, tree);
> ! static tree push_cp_library_fn (enum tree_code, tree);
> ! static tree build_cp_library_fn (tree, enum tree_code, tree);
>   static void store_parm_decls (tree);
>   static void initialize_local_var (tree, tree);
>   static void expand_static_init (tree, tree);
> --- 106,113 ----
>   static void initialize_predefined_identifiers (void);
>   static tree check_special_function_return_type
>         (special_function_kind, tree, tree);
> ! static tree push_cp_library_fn (enum tree_code, tree, int);
> ! static tree build_cp_library_fn (tree, enum tree_code, tree, int);
>   static void store_parm_decls (tree);
>   static void initialize_local_var (tree, tree);
>   static void expand_static_init (tree, tree);
> *************** cxx_init_decl_processing (void)
> *** 3800,3809 ****
>       newtype = build_exception_variant (newtype, new_eh_spec);
>       deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
>       deltype = build_exception_variant (deltype, empty_except_spec);
> !     push_cp_library_fn (NEW_EXPR, newtype);
> !     push_cp_library_fn (VEC_NEW_EXPR, newtype);
> !     global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
> !     push_cp_library_fn (VEC_DELETE_EXPR, deltype);
>
>       nullptr_type_node = make_node (NULLPTR_TYPE);
>       TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
> --- 3799,3808 ----
>       newtype = build_exception_variant (newtype, new_eh_spec);
>       deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
>       deltype = build_exception_variant (deltype, empty_except_spec);
> !     push_cp_library_fn (NEW_EXPR, newtype, 0);
> !     push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
> !     global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
> !     push_cp_library_fn (VEC_DELETE_EXPR, deltype);
>
>       nullptr_type_node = make_node (NULLPTR_TYPE);
>       TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
> *************** cxx_init_decl_processing (void)
> *** 3816,3822 ****
>     }
>
>     abort_fndecl
> !     = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype);
>
>     /* Perform other language dependent initializations.  */
>     init_class_processing ();
> --- 3815,3822 ----
>     }
>
>     abort_fndecl
> !     = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype,
> !                           ECF_NORETURN | ECF_NOTHROW);
>
>     /* Perform other language dependent initializations.  */
>     init_class_processing ();
> *************** cxx_builtin_function_ext_scope (tree dec
> *** 4007,4013 ****
>      function.  Not called directly.  */
>
>   static tree
> ! build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
>   {
>     tree fn = build_lang_decl (FUNCTION_DECL, name, type);
>     DECL_EXTERNAL (fn) = 1;
> --- 4007,4014 ----
>      function.  Not called directly.  */
>
>   static tree
> ! build_library_fn (tree name, enum tree_code operator_code, tree type,
> !                 int ecf_flags)
>   {
>     tree fn = build_lang_decl (FUNCTION_DECL, name, type);
>     DECL_EXTERNAL (fn) = 1;
> *************** build_library_fn_1 (tree name, enum tree
> *** 4019,4046 ****
>        external shared object.  */
>     DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
>     DECL_VISIBILITY_SPECIFIED (fn) = 1;
> !   return fn;
> ! }
> !
> ! /* Returns the _DECL for a library function with C linkage.
> !    We assume that such functions never throw; if this is incorrect,
> !    callers should unset TREE_NOTHROW.  */
> !
> ! static tree
> ! build_library_fn (tree name, tree type)
> ! {
> !   tree fn = build_library_fn_1 (name, ERROR_MARK, type);
> !   TREE_NOTHROW (fn) = 1;
>     return fn;
>   }
>
>   /* Returns the _DECL for a library function with C++ linkage.  */
>
>   static tree
> ! build_cp_library_fn (tree name, enum tree_code operator_code, tree type)
>   {
> !   tree fn = build_library_fn_1 (name, operator_code, type);
> !   TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
>     DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
>     SET_DECL_LANGUAGE (fn, lang_cplusplus);
>     return fn;
> --- 4020,4036 ----
>        external shared object.  */
>     DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
>     DECL_VISIBILITY_SPECIFIED (fn) = 1;
> !   set_call_expr_flags (fn, ecf_flags);
>     return fn;
>   }
>
>   /* Returns the _DECL for a library function with C++ linkage.  */
>
>   static tree
> ! build_cp_library_fn (tree name, enum tree_code operator_code, tree type,
> !                    int ecf_flags)
>   {
> !   tree fn = build_library_fn (name, operator_code, type, ecf_flags);
>     DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
>     SET_DECL_LANGUAGE (fn, lang_cplusplus);
>     return fn;
> *************** build_cp_library_fn (tree name, enum tre
> *** 4050,4067 ****
>      IDENTIFIER_NODE.  */
>
>   tree
> ! build_library_fn_ptr (const char* name, tree type)
>   {
> !   return build_library_fn (get_identifier (name), type);
>   }
>
>   /* Like build_cp_library_fn, but takes a C string instead of an
>      IDENTIFIER_NODE.  */
>
>   tree
> ! build_cp_library_fn_ptr (const char* name, tree type)
>   {
> !   return build_cp_library_fn (get_identifier (name), ERROR_MARK, type);
>   }
>
>   /* Like build_library_fn, but also pushes the function so that we will
> --- 4040,4058 ----
>      IDENTIFIER_NODE.  */
>
>   tree
> ! build_library_fn_ptr (const char* name, tree type, int ecf_flags)
>   {
> !   return build_library_fn (get_identifier (name), ERROR_MARK, type, ecf_flags);
>   }
>
>   /* Like build_cp_library_fn, but takes a C string instead of an
>      IDENTIFIER_NODE.  */
>
>   tree
> ! build_cp_library_fn_ptr (const char* name, tree type, int ecf_flags)
>   {
> !   return build_cp_library_fn (get_identifier (name), ERROR_MARK, type,
> !                             ecf_flags);
>   }
>
>   /* Like build_library_fn, but also pushes the function so that we will
> *************** build_cp_library_fn_ptr (const char* nam
> *** 4069,4082 ****
>      may throw exceptions listed in RAISES.  */
>
>   tree
> ! push_library_fn (tree name, tree type, tree raises)
>   {
>     tree fn;
>
>     if (raises)
>       type = build_exception_variant (type, raises);
>
> !   fn = build_library_fn (name, type);
>     pushdecl_top_level (fn);
>     return fn;
>   }
> --- 4060,4073 ----
>      may throw exceptions listed in RAISES.  */
>
>   tree
> ! push_library_fn (tree name, tree type, tree raises, int ecf_flags)
>   {
>     tree fn;
>
>     if (raises)
>       type = build_exception_variant (type, raises);
>
> !   fn = build_library_fn (name, ERROR_MARK, type, ecf_flags);
>     pushdecl_top_level (fn);
>     return fn;
>   }
> *************** push_library_fn (tree name, tree type, t
> *** 4085,4095 ****
>      will be found by normal lookup.  */
>
>   static tree
> ! push_cp_library_fn (enum tree_code operator_code, tree type)
>   {
>     tree fn = build_cp_library_fn (ansi_opname (operator_code),
>                                  operator_code,
> !                                type);
>     pushdecl (fn);
>     if (flag_tm)
>       apply_tm_attr (fn, get_identifier ("transaction_safe"));
> --- 4076,4087 ----
>      will be found by normal lookup.  */
>
>   static tree
> ! push_cp_library_fn (enum tree_code operator_code, tree type,
> !                   int ecf_flags)
>   {
>     tree fn = build_cp_library_fn (ansi_opname (operator_code),
>                                  operator_code,
> !                                type, ecf_flags);
>     pushdecl (fn);
>     if (flag_tm)
>       apply_tm_attr (fn, get_identifier ("transaction_safe"));
> *************** push_cp_library_fn (enum tree_code opera
> *** 4100,4109 ****
>      a FUNCTION_TYPE.  */
>
>   tree
> ! push_void_library_fn (tree name, tree parmtypes)
>   {
>     tree type = build_function_type (void_type_node, parmtypes);
> !   return push_library_fn (name, type, NULL_TREE);
>   }
>
>   /* Like push_library_fn, but also note that this function throws
> --- 4092,4101 ----
>      a FUNCTION_TYPE.  */
>
>   tree
> ! push_void_library_fn (tree name, tree parmtypes, int ecf_flags)
>   {
>     tree type = build_function_type (void_type_node, parmtypes);
> !   return push_library_fn (name, type, NULL_TREE, ecf_flags);
>   }
>
>   /* Like push_library_fn, but also note that this function throws
> *************** push_void_library_fn (tree name, tree pa
> *** 4112,4120 ****
>   tree
>   push_throw_library_fn (tree name, tree type)
>   {
> !   tree fn = push_library_fn (name, type, NULL_TREE);
> !   TREE_THIS_VOLATILE (fn) = 1;
> !   TREE_NOTHROW (fn) = 0;
>     return fn;
>   }
>
> --- 4104,4110 ----
>   tree
>   push_throw_library_fn (tree name, tree type)
>   {
> !   tree fn = push_library_fn (name, type, NULL_TREE, ECF_NORETURN);
>     return fn;
>   }
>
> *************** get_atexit_node (void)
> *** 6644,6650 ****
>
>     /* Now, build the function declaration.  */
>     push_lang_context (lang_name_c);
> !   atexit_fndecl = build_library_fn_ptr (name, fn_type);
>     mark_used (atexit_fndecl);
>     pop_lang_context ();
>     atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error);
> --- 6634,6640 ----
>
>     /* Now, build the function declaration.  */
>     push_lang_context (lang_name_c);
> !   atexit_fndecl = build_library_fn_ptr (name, fn_type, ECF_LEAF | ECF_NOTHROW);
>     mark_used (atexit_fndecl);
>     pop_lang_context ();
>     atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error);
> *************** get_thread_atexit_node (void)
> *** 6666,6672 ****
>                                            NULL_TREE);
>
>     /* Now, build the function declaration.  */
> !   tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type);
>     return decay_conversion (atexit_fndecl, tf_warning_or_error);
>   }
>
> --- 6656,6663 ----
>                                            NULL_TREE);
>
>     /* Now, build the function declaration.  */
> !   tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type,
> !                                            ECF_LEAF | ECF_NOTHROW);
>     return decay_conversion (atexit_fndecl, tf_warning_or_error);
>   }
>
> *************** expand_static_init (tree decl, tree init
> *** 6992,7006 ****
>               (acquire_name, build_function_type_list (integer_type_node,
>                                                        TREE_TYPE (guard_addr),
>                                                        NULL_TREE),
> !              NULL_TREE);
>           if (!release_fn || !abort_fn)
>             vfntype = build_function_type_list (void_type_node,
>                                                 TREE_TYPE (guard_addr),
>                                                 NULL_TREE);
>           if (!release_fn)
> !           release_fn = push_library_fn (release_name, vfntype, NULL_TREE);
>           if (!abort_fn)
> !           abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE);
>
>           inner_if_stmt = begin_if_stmt ();
>           finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
> --- 6983,6999 ----
>               (acquire_name, build_function_type_list (integer_type_node,
>                                                        TREE_TYPE (guard_addr),
>                                                        NULL_TREE),
> !              NULL_TREE, ECF_NOTHROW | ECF_LEAF);
>           if (!release_fn || !abort_fn)
>             vfntype = build_function_type_list (void_type_node,
>                                                 TREE_TYPE (guard_addr),
>                                                 NULL_TREE);
>           if (!release_fn)
> !           release_fn = push_library_fn (release_name, vfntype, NULL_TREE,
> !                                          ECF_NOTHROW | ECF_LEAF);
>           if (!abort_fn)
> !           abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE,
> !                                       ECF_NOTHROW | ECF_LEAF);
>
>           inner_if_stmt = begin_if_stmt ();
>           finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
> Index: cp/except.c
> ===================================================================
> *** cp/except.c (revision 201910)
> --- cp/except.c (working copy)
> *************** init_exception_processing (void)
> *** 57,63 ****
>     /* 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);
>     TREE_THIS_VOLATILE (terminate_node) = 1;
>     TREE_NOTHROW (terminate_node) = 1;
>     pop_namespace ();
> --- 57,64 ----
>     /* 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,
> !                                          ECF_NOTHROW | ECF_NORETURN);
>     TREE_THIS_VOLATILE (terminate_node) = 1;
>     TREE_NOTHROW (terminate_node) = 1;
>     pop_namespace ();
> *************** build_exc_ptr (void)
> *** 149,160 ****
>      are consistent with the actual implementations in libsupc++.  */
>
>   static tree
> ! declare_nothrow_library_fn (tree name, tree return_type, tree parm_type)
>   {
>     return push_library_fn (name, build_function_type_list (return_type,
>                                                           parm_type,
>                                                           NULL_TREE),
> !                         empty_except_spec);
>   }
>
>   /* Build up a call to __cxa_get_exception_ptr so that we can build a
> --- 150,162 ----
>      are consistent with the actual implementations in libsupc++.  */
>
>   static tree
> ! declare_library_fn (tree name, tree return_type, tree parm_type, int ecf_flags)
>   {
>     return push_library_fn (name, build_function_type_list (return_type,
>                                                           parm_type,
>                                                           NULL_TREE),
> !                         empty_except_spec,
> !                         ecf_flags);
>   }
>
>   /* Build up a call to __cxa_get_exception_ptr so that we can build a
> *************** do_get_exception_ptr (void)
> *** 169,178 ****
>     if (!get_global_value_if_present (fn, &fn))
>       {
>         /* Declare void* __cxa_get_exception_ptr (void *) throw().  */
> !       fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
> !
> !       if (flag_tm)
> !       apply_tm_attr (fn, get_identifier ("transaction_pure"));
>       }
>
>     return cp_build_function_call_nary (fn, tf_warning_or_error,
> --- 171,178 ----
>     if (!get_global_value_if_present (fn, &fn))
>       {
>         /* Declare void* __cxa_get_exception_ptr (void *) throw().  */
> !       fn = declare_library_fn (fn, ptr_type_node, ptr_type_node,
> !                              ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE);
>       }
>
>     return cp_build_function_call_nary (fn, tf_warning_or_error,
> *************** do_begin_catch (void)
> *** 191,206 ****
>     if (!get_global_value_if_present (fn, &fn))
>       {
>         /* Declare void* __cxa_begin_catch (void *) throw().  */
> !       fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
>
>         /* Create its transactional-memory equivalent.  */
>         if (flag_tm)
>         {
>           tree fn2 = get_identifier ("_ITM_cxa_begin_catch");
>           if (!get_global_value_if_present (fn2, &fn2))
> !           fn2 = declare_nothrow_library_fn (fn2, ptr_type_node,
> !                                             ptr_type_node);
> !         apply_tm_attr (fn2, get_identifier ("transaction_pure"));
>           record_tm_replacement (fn, fn2);
>         }
>       }
> --- 191,205 ----
>     if (!get_global_value_if_present (fn, &fn))
>       {
>         /* Declare void* __cxa_begin_catch (void *) throw().  */
> !       fn = declare_library_fn (fn, ptr_type_node, ptr_type_node, ECF_NOTHROW);
>
>         /* Create its transactional-memory equivalent.  */
>         if (flag_tm)
>         {
>           tree fn2 = get_identifier ("_ITM_cxa_begin_catch");
>           if (!get_global_value_if_present (fn2, &fn2))
> !           fn2 = declare_library_fn (fn2, ptr_type_node,
> !                                     ptr_type_node, ECF_NOTHROW | ECF_TM_PURE);
>           record_tm_replacement (fn, fn2);
>         }
>       }
> *************** do_end_catch (tree type)
> *** 238,258 ****
>     fn = get_identifier ("__cxa_end_catch");
>     if (!get_global_value_if_present (fn, &fn))
>       {
> !       /* Declare void __cxa_end_catch ().  */
> !       fn = push_void_library_fn (fn, void_list_node);
> !       /* This can throw if the destructor for the exception throws.  */
> !       TREE_NOTHROW (fn) = 0;
>
>         /* Create its transactional-memory equivalent.  */
>         if (flag_tm)
>         {
>           tree fn2 = get_identifier ("_ITM_cxa_end_catch");
>           if (!get_global_value_if_present (fn2, &fn2))
> !           {
> !             fn2 = push_void_library_fn (fn2, void_list_node);
> !             TREE_NOTHROW (fn2) = 0;
> !           }
> !         apply_tm_attr (fn2, get_identifier ("transaction_pure"));
>           record_tm_replacement (fn, fn2);
>         }
>       }
> --- 237,252 ----
>     fn = get_identifier ("__cxa_end_catch");
>     if (!get_global_value_if_present (fn, &fn))
>       {
> !       /* Declare void __cxa_end_catch ().
> !          This can throw if the destructor for the exception throws.  */
> !       fn = push_void_library_fn (fn, void_list_node, 0);
>
>         /* Create its transactional-memory equivalent.  */
>         if (flag_tm)
>         {
>           tree fn2 = get_identifier ("_ITM_cxa_end_catch");
>           if (!get_global_value_if_present (fn2, &fn2))
> !           fn2 = push_void_library_fn (fn2, void_list_node, ECF_TM_PURE);
>           record_tm_replacement (fn, fn2);
>         }
>       }
> *************** do_allocate_exception (tree type)
> *** 631,645 ****
>     if (!get_global_value_if_present (fn, &fn))
>       {
>         /* Declare void *__cxa_allocate_exception(size_t) throw().  */
> !       fn = declare_nothrow_library_fn (fn, ptr_type_node, size_type_node);
>
>         if (flag_tm)
>         {
>           tree fn2 = get_identifier ("_ITM_cxa_allocate_exception");
>           if (!get_global_value_if_present (fn2, &fn2))
> !           fn2 = declare_nothrow_library_fn (fn2, ptr_type_node,
> !                                             size_type_node);
> !         apply_tm_attr (fn2, get_identifier ("transaction_pure"));
>           record_tm_replacement (fn, fn2);
>         }
>       }
> --- 625,640 ----
>     if (!get_global_value_if_present (fn, &fn))
>       {
>         /* Declare void *__cxa_allocate_exception(size_t) throw().  */
> !       fn = declare_library_fn (fn, ptr_type_node, size_type_node,
> !                               ECF_NOTHROW | ECF_MALLOC);
>
>         if (flag_tm)
>         {
>           tree fn2 = get_identifier ("_ITM_cxa_allocate_exception");
>           if (!get_global_value_if_present (fn2, &fn2))
> !           fn2 = declare_library_fn (fn2, ptr_type_node,
> !                                     size_type_node,
> !                                     ECF_NOTHROW | ECF_MALLOC | ECF_TM_PURE);
>           record_tm_replacement (fn, fn2);
>         }
>       }
> *************** do_free_exception (tree ptr)
> *** 660,666 ****
>     if (!get_global_value_if_present (fn, &fn))
>       {
>         /* Declare void __cxa_free_exception (void *) throw().  */
> !       fn = declare_nothrow_library_fn (fn, void_type_node, ptr_type_node);
>       }
>
>     return cp_build_function_call_nary (fn, tf_warning_or_error, ptr, NULL_TREE);
> --- 655,662 ----
>     if (!get_global_value_if_present (fn, &fn))
>       {
>         /* Declare void __cxa_free_exception (void *) throw().  */
> !       fn = declare_library_fn (fn, void_type_node, ptr_type_node,
> !                              ECF_NOTHROW | ECF_LEAF);
>       }
>
>     return cp_build_function_call_nary (fn, tf_warning_or_error, ptr, NULL_TREE);
> Index: cp/rtti.c
> ===================================================================
> *** cp/rtti.c   (revision 201910)
> --- cp/rtti.c   (working copy)
> *************** build_dynamic_cast_1 (tree type, tree ex
> *** 739,745 ****
>                                               const_ptr_type_node,
>                                               tinfo_ptr, tinfo_ptr,
>                                               ptrdiff_type_node, NULL_TREE);
> !             dcast_fn = build_library_fn_ptr (name, tmp);
> !             DECL_PURE_P (dcast_fn) = 1;
>               pop_abi_namespace ();
>               dynamic_cast_node = dcast_fn;
> --- 739,745 ----
>                                               const_ptr_type_node,
>                                               tinfo_ptr, tinfo_ptr,
>                                               ptrdiff_type_node, NULL_TREE);
> !             dcast_fn = build_library_fn_ptr (name, tmp,
> !                                              ECF_LEAF | ECF_PURE | ECF_NOTHROW);
>               pop_abi_namespace ();
>               dynamic_cast_node = dcast_fn;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]