diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 39 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 8 | ||||
-rw-r--r-- | gcc/cp/decl.c | 77 | ||||
-rw-r--r-- | gcc/cp/except.c | 51 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 4 |
6 files changed, 107 insertions, 74 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f848b813f2e..2b2f45aab00 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,42 @@ +2013-08-29 Jan Hubicka <jh@suse.cz> + + * class.c (build_vtbl_initializer): Make __cxa_deleted_virtual + ECF_NORETURN | ECF_LEAF + * 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 | ECF_LEAF. + (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 | ECF_LEAF. + (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 | ECF_LEAF. + (do_end_catch): __cxa_end_catch and _ITM_cxa_end_catch is + ECF_LEAF. + (do_allocate_exception): _cxa_allocate_exception + and _ITM_cxa_allocate_exception are ECF_NOTHROW | ECF_MALLOC + | ECF_LEAF + (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. + 2013-08-29 Adam Butcher <adam@jessamine.co.uk> * error.c (dump_lambda_function): New function, dependent on ... diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 596b13d2695..3f77d22fcc9 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -8873,7 +8873,7 @@ build_vtbl_initializer (tree binfo, if (!get_global_value_if_present (fn, &fn)) fn = push_library_fn (fn, (build_function_type_list (void_type_node, NULL_TREE)), - NULL_TREE); + NULL_TREE, ECF_NORETURN | ECF_LEAF); if (!TARGET_VTABLE_USES_DESCRIPTORS) init = fold_convert (vfunc_ptr_type_node, build_fold_addr_expr (fn)); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 876a72aafed..73f6a6ad43b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5170,10 +5170,10 @@ extern void check_goto (tree); 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 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); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 4076a24cf6a..bead6e84183 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -75,7 +75,6 @@ static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *, 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); @@ -107,8 +106,8 @@ static tree cp_make_fname_decl (location_t, tree, int); 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 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); @@ -3800,10 +3799,10 @@ cxx_init_decl_processing (void) 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); + 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, ECF_NOTHROW); nullptr_type_node = make_node (NULLPTR_TYPE); TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode)); @@ -3816,7 +3815,8 @@ cxx_init_decl_processing (void) } abort_fndecl - = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype); + = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype, + ECF_NORETURN | ECF_NOTHROW | ECF_LEAF); /* Perform other language dependent initializations. */ init_class_processing (); @@ -4007,7 +4007,8 @@ cxx_builtin_function_ext_scope (tree decl) function. Not called directly. */ static tree -build_library_fn_1 (tree name, enum tree_code operator_code, tree type) +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; @@ -4019,28 +4020,17 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type) 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; + 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) +build_cp_library_fn (tree name, enum tree_code operator_code, tree type, + int ecf_flags) { - tree fn = build_library_fn_1 (name, operator_code, type); - TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type); + 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; @@ -4050,18 +4040,19 @@ build_cp_library_fn (tree name, enum tree_code operator_code, tree type) IDENTIFIER_NODE. */ tree -build_library_fn_ptr (const char* name, tree type) +build_library_fn_ptr (const char* name, tree type, int ecf_flags) { - return build_library_fn (get_identifier (name), type); + 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) +build_cp_library_fn_ptr (const char* name, tree type, int ecf_flags) { - return build_cp_library_fn (get_identifier (name), ERROR_MARK, type); + 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 @@ -4069,14 +4060,14 @@ build_cp_library_fn_ptr (const char* name, tree type) may throw exceptions listed in RAISES. */ tree -push_library_fn (tree name, tree type, tree raises) +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, type); + fn = build_library_fn (name, ERROR_MARK, type, ecf_flags); pushdecl_top_level (fn); return fn; } @@ -4085,11 +4076,12 @@ push_library_fn (tree name, tree type, tree raises) will be found by normal lookup. */ static tree -push_cp_library_fn (enum tree_code operator_code, tree type) +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); + type, ecf_flags); pushdecl (fn); if (flag_tm) apply_tm_attr (fn, get_identifier ("transaction_safe")); @@ -4100,10 +4092,10 @@ push_cp_library_fn (enum tree_code operator_code, tree type) a FUNCTION_TYPE. */ tree -push_void_library_fn (tree name, tree parmtypes) +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); + return push_library_fn (name, type, NULL_TREE, ecf_flags); } /* Like push_library_fn, but also note that this function throws @@ -4112,9 +4104,7 @@ push_void_library_fn (tree name, tree parmtypes) 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; + tree fn = push_library_fn (name, type, NULL_TREE, ECF_NORETURN | ECF_LEAF); return fn; } @@ -6644,7 +6634,7 @@ get_atexit_node (void) /* Now, build the function declaration. */ push_lang_context (lang_name_c); - atexit_fndecl = build_library_fn_ptr (name, fn_type); + 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); @@ -6666,7 +6656,8 @@ get_thread_atexit_node (void) NULL_TREE); /* Now, build the function declaration. */ - tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type); + 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); } @@ -6992,15 +6983,17 @@ expand_static_init (tree decl, tree init) (acquire_name, build_function_type_list (integer_type_node, TREE_TYPE (guard_addr), NULL_TREE), - 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); + 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); + 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), diff --git a/gcc/cp/except.c b/gcc/cp/except.c index be003d2994b..164b35c3a73 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -57,7 +57,9 @@ 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_node = build_cp_library_fn_ptr ("terminate", tmp, + ECF_NOTHROW | ECF_NORETURN + | ECF_LEAF); TREE_THIS_VOLATILE (terminate_node) = 1; TREE_NOTHROW (terminate_node) = 1; pop_namespace (); @@ -149,12 +151,13 @@ build_exc_ptr (void) are consistent with the actual implementations in libsupc++. */ static tree -declare_nothrow_library_fn (tree name, tree return_type, tree parm_type) +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); + empty_except_spec, + ecf_flags); } /* Build up a call to __cxa_get_exception_ptr so that we can build a @@ -169,10 +172,8 @@ do_get_exception_ptr (void) 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")); + 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, @@ -191,16 +192,17 @@ do_begin_catch (void) 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); + fn = declare_library_fn (fn, ptr_type_node, ptr_type_node, + ECF_NOTHROW | ECF_LEAF); /* 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")); + fn2 = declare_library_fn (fn2, ptr_type_node, + ptr_type_node, + ECF_NOTHROW | ECF_TM_PURE | ECF_LEAF); record_tm_replacement (fn, fn2); } } @@ -238,21 +240,17 @@ do_end_catch (tree type) 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; + /* Declare void __cxa_end_catch (). + This can throw if the destructor for the exception throws. */ + fn = push_void_library_fn (fn, void_list_node, ECF_LEAF); /* 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")); + fn2 = push_void_library_fn (fn2, void_list_node, + ECF_TM_PURE | ECF_LEAF); record_tm_replacement (fn, fn2); } } @@ -631,15 +629,17 @@ do_allocate_exception (tree type) 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); + fn = declare_library_fn (fn, ptr_type_node, size_type_node, + ECF_NOTHROW | ECF_MALLOC | ECF_LEAF); 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")); + fn2 = declare_library_fn (fn2, ptr_type_node, + size_type_node, + ECF_NOTHROW | ECF_MALLOC | ECF_TM_PURE + | ECF_LEAF); record_tm_replacement (fn, fn2); } } @@ -660,7 +660,8 @@ do_free_exception (tree ptr) 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); + 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); diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index f3094981dfb..5827540c9b2 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -739,8 +739,8 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) 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; + dcast_fn = build_library_fn_ptr (name, tmp, + ECF_LEAF | ECF_PURE | ECF_NOTHROW); pop_abi_namespace (); dynamic_cast_node = dcast_fn; } |