Commit fafa0521 by Jan Hubicka Committed by Jan Hubicka

class.c (build_vtbl_initializer): Make __cxa_deleted_virtual ECF_NORETURN | ECF_LEAF

	* 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.

From-SVN: r202099
parent 47500756
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> 2013-08-29 Adam Butcher <adam@jessamine.co.uk>
* error.c (dump_lambda_function): New function, dependent on ... * error.c (dump_lambda_function): New function, dependent on ...
......
...@@ -8873,7 +8873,7 @@ build_vtbl_initializer (tree binfo, ...@@ -8873,7 +8873,7 @@ build_vtbl_initializer (tree binfo,
if (!get_global_value_if_present (fn, &fn)) if (!get_global_value_if_present (fn, &fn))
fn = push_library_fn (fn, (build_function_type_list fn = push_library_fn (fn, (build_function_type_list
(void_type_node, NULL_TREE)), (void_type_node, NULL_TREE)),
NULL_TREE); NULL_TREE, ECF_NORETURN | ECF_LEAF);
if (!TARGET_VTABLE_USES_DESCRIPTORS) if (!TARGET_VTABLE_USES_DESCRIPTORS)
init = fold_convert (vfunc_ptr_type_node, init = fold_convert (vfunc_ptr_type_node,
build_fold_addr_expr (fn)); build_fold_addr_expr (fn));
......
...@@ -5170,10 +5170,10 @@ extern void check_goto (tree); ...@@ -5170,10 +5170,10 @@ extern void check_goto (tree);
extern bool check_omp_return (void); extern bool check_omp_return (void);
extern tree make_typename_type (tree, tree, enum tag_types, tsubst_flags_t); 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 make_unbound_class_template (tree, tree, tree, tsubst_flags_t);
extern tree build_library_fn_ptr (const char *, tree); extern tree build_library_fn_ptr (const char *, tree, int);
extern tree build_cp_library_fn_ptr (const char *, tree); extern tree build_cp_library_fn_ptr (const char *, tree, int);
extern tree push_library_fn (tree, tree, tree); extern tree push_library_fn (tree, tree, tree, int);
extern tree push_void_library_fn (tree, tree); extern tree push_void_library_fn (tree, tree, int);
extern tree push_throw_library_fn (tree, tree); extern tree push_throw_library_fn (tree, tree);
extern void warn_misplaced_attr_for_class_type (source_location location, extern void warn_misplaced_attr_for_class_type (source_location location,
tree class_type); tree class_type);
......
...@@ -75,7 +75,6 @@ static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *, ...@@ -75,7 +75,6 @@ static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
static int check_static_variable_definition (tree, tree); static int check_static_variable_definition (tree, tree);
static void record_unknown_type (tree, const char *); static void record_unknown_type (tree, const char *);
static tree builtin_function_1 (tree, tree, bool); 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 int member_function_or_else (tree, tree, enum overload_flags);
static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int, static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int,
int); int);
...@@ -107,8 +106,8 @@ static tree cp_make_fname_decl (location_t, tree, int); ...@@ -107,8 +106,8 @@ static tree cp_make_fname_decl (location_t, tree, int);
static void initialize_predefined_identifiers (void); static void initialize_predefined_identifiers (void);
static tree check_special_function_return_type static tree check_special_function_return_type
(special_function_kind, tree, tree); (special_function_kind, tree, tree);
static tree push_cp_library_fn (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); static tree build_cp_library_fn (tree, enum tree_code, tree, int);
static void store_parm_decls (tree); static void store_parm_decls (tree);
static void initialize_local_var (tree, tree); static void initialize_local_var (tree, tree);
static void expand_static_init (tree, tree); static void expand_static_init (tree, tree);
...@@ -3800,10 +3799,10 @@ cxx_init_decl_processing (void) ...@@ -3800,10 +3799,10 @@ cxx_init_decl_processing (void)
newtype = build_exception_variant (newtype, new_eh_spec); newtype = build_exception_variant (newtype, new_eh_spec);
deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr); deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
deltype = build_exception_variant (deltype, empty_except_spec); deltype = build_exception_variant (deltype, empty_except_spec);
push_cp_library_fn (NEW_EXPR, newtype); push_cp_library_fn (NEW_EXPR, newtype, 0);
push_cp_library_fn (VEC_NEW_EXPR, newtype); push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype); global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
push_cp_library_fn (VEC_DELETE_EXPR, deltype); push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
nullptr_type_node = make_node (NULLPTR_TYPE); nullptr_type_node = make_node (NULLPTR_TYPE);
TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode)); TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
...@@ -3816,7 +3815,8 @@ cxx_init_decl_processing (void) ...@@ -3816,7 +3815,8 @@ cxx_init_decl_processing (void)
} }
abort_fndecl 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. */ /* Perform other language dependent initializations. */
init_class_processing (); init_class_processing ();
...@@ -4007,7 +4007,8 @@ cxx_builtin_function_ext_scope (tree decl) ...@@ -4007,7 +4007,8 @@ cxx_builtin_function_ext_scope (tree decl)
function. Not called directly. */ function. Not called directly. */
static tree 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); tree fn = build_lang_decl (FUNCTION_DECL, name, type);
DECL_EXTERNAL (fn) = 1; DECL_EXTERNAL (fn) = 1;
...@@ -4019,28 +4020,17 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type) ...@@ -4019,28 +4020,17 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
external shared object. */ external shared object. */
DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT; DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
DECL_VISIBILITY_SPECIFIED (fn) = 1; DECL_VISIBILITY_SPECIFIED (fn) = 1;
return fn; set_call_expr_flags (fn, ecf_flags);
}
/* 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; return fn;
} }
/* Returns the _DECL for a library function with C++ linkage. */ /* Returns the _DECL for a library function with C++ linkage. */
static tree 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 fn = build_library_fn (name, operator_code, type, ecf_flags);
TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace); DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
SET_DECL_LANGUAGE (fn, lang_cplusplus); SET_DECL_LANGUAGE (fn, lang_cplusplus);
return fn; return fn;
...@@ -4050,18 +4040,19 @@ build_cp_library_fn (tree name, enum tree_code operator_code, tree type) ...@@ -4050,18 +4040,19 @@ build_cp_library_fn (tree name, enum tree_code operator_code, tree type)
IDENTIFIER_NODE. */ IDENTIFIER_NODE. */
tree 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 /* Like build_cp_library_fn, but takes a C string instead of an
IDENTIFIER_NODE. */ IDENTIFIER_NODE. */
tree 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 /* 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) ...@@ -4069,14 +4060,14 @@ build_cp_library_fn_ptr (const char* name, tree type)
may throw exceptions listed in RAISES. */ may throw exceptions listed in RAISES. */
tree tree
push_library_fn (tree name, tree type, tree raises) push_library_fn (tree name, tree type, tree raises, int ecf_flags)
{ {
tree fn; tree fn;
if (raises) if (raises)
type = build_exception_variant (type, 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); pushdecl_top_level (fn);
return fn; return fn;
} }
...@@ -4085,11 +4076,12 @@ push_library_fn (tree name, tree type, tree raises) ...@@ -4085,11 +4076,12 @@ push_library_fn (tree name, tree type, tree raises)
will be found by normal lookup. */ will be found by normal lookup. */
static tree 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), tree fn = build_cp_library_fn (ansi_opname (operator_code),
operator_code, operator_code,
type); type, ecf_flags);
pushdecl (fn); pushdecl (fn);
if (flag_tm) if (flag_tm)
apply_tm_attr (fn, get_identifier ("transaction_safe")); apply_tm_attr (fn, get_identifier ("transaction_safe"));
...@@ -4100,10 +4092,10 @@ push_cp_library_fn (enum tree_code operator_code, tree type) ...@@ -4100,10 +4092,10 @@ push_cp_library_fn (enum tree_code operator_code, tree type)
a FUNCTION_TYPE. */ a FUNCTION_TYPE. */
tree 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); 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 /* Like push_library_fn, but also note that this function throws
...@@ -4112,9 +4104,7 @@ push_void_library_fn (tree name, tree parmtypes) ...@@ -4112,9 +4104,7 @@ push_void_library_fn (tree name, tree parmtypes)
tree tree
push_throw_library_fn (tree name, tree type) push_throw_library_fn (tree name, tree type)
{ {
tree fn = push_library_fn (name, type, NULL_TREE); tree fn = push_library_fn (name, type, NULL_TREE, ECF_NORETURN | ECF_LEAF);
TREE_THIS_VOLATILE (fn) = 1;
TREE_NOTHROW (fn) = 0;
return fn; return fn;
} }
...@@ -6644,7 +6634,7 @@ get_atexit_node (void) ...@@ -6644,7 +6634,7 @@ get_atexit_node (void)
/* Now, build the function declaration. */ /* Now, build the function declaration. */
push_lang_context (lang_name_c); 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); mark_used (atexit_fndecl);
pop_lang_context (); pop_lang_context ();
atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error); atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error);
...@@ -6666,7 +6656,8 @@ get_thread_atexit_node (void) ...@@ -6666,7 +6656,8 @@ get_thread_atexit_node (void)
NULL_TREE); NULL_TREE);
/* Now, build the function declaration. */ /* 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); return decay_conversion (atexit_fndecl, tf_warning_or_error);
} }
...@@ -6992,15 +6983,17 @@ expand_static_init (tree decl, tree init) ...@@ -6992,15 +6983,17 @@ expand_static_init (tree decl, tree init)
(acquire_name, build_function_type_list (integer_type_node, (acquire_name, build_function_type_list (integer_type_node,
TREE_TYPE (guard_addr), TREE_TYPE (guard_addr),
NULL_TREE), NULL_TREE),
NULL_TREE); NULL_TREE, ECF_NOTHROW | ECF_LEAF);
if (!release_fn || !abort_fn) if (!release_fn || !abort_fn)
vfntype = build_function_type_list (void_type_node, vfntype = build_function_type_list (void_type_node,
TREE_TYPE (guard_addr), TREE_TYPE (guard_addr),
NULL_TREE); NULL_TREE);
if (!release_fn) 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) 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 (); inner_if_stmt = begin_if_stmt ();
finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr), finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
......
...@@ -57,7 +57,9 @@ init_exception_processing (void) ...@@ -57,7 +57,9 @@ init_exception_processing (void)
/* void std::terminate (); */ /* void std::terminate (); */
push_namespace (std_identifier); push_namespace (std_identifier);
tmp = build_function_type_list (void_type_node, NULL_TREE); 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_THIS_VOLATILE (terminate_node) = 1;
TREE_NOTHROW (terminate_node) = 1; TREE_NOTHROW (terminate_node) = 1;
pop_namespace (); pop_namespace ();
...@@ -149,12 +151,13 @@ build_exc_ptr (void) ...@@ -149,12 +151,13 @@ build_exc_ptr (void)
are consistent with the actual implementations in libsupc++. */ are consistent with the actual implementations in libsupc++. */
static tree 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, return push_library_fn (name, build_function_type_list (return_type,
parm_type, parm_type,
NULL_TREE), 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 /* Build up a call to __cxa_get_exception_ptr so that we can build a
...@@ -169,10 +172,8 @@ do_get_exception_ptr (void) ...@@ -169,10 +172,8 @@ do_get_exception_ptr (void)
if (!get_global_value_if_present (fn, &fn)) if (!get_global_value_if_present (fn, &fn))
{ {
/* Declare void* __cxa_get_exception_ptr (void *) throw(). */ /* Declare void* __cxa_get_exception_ptr (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_PURE | ECF_LEAF | ECF_TM_PURE);
if (flag_tm)
apply_tm_attr (fn, get_identifier ("transaction_pure"));
} }
return cp_build_function_call_nary (fn, tf_warning_or_error, return cp_build_function_call_nary (fn, tf_warning_or_error,
...@@ -191,16 +192,17 @@ do_begin_catch (void) ...@@ -191,16 +192,17 @@ do_begin_catch (void)
if (!get_global_value_if_present (fn, &fn)) if (!get_global_value_if_present (fn, &fn))
{ {
/* Declare void* __cxa_begin_catch (void *) throw(). */ /* 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. */ /* Create its transactional-memory equivalent. */
if (flag_tm) if (flag_tm)
{ {
tree fn2 = get_identifier ("_ITM_cxa_begin_catch"); tree fn2 = get_identifier ("_ITM_cxa_begin_catch");
if (!get_global_value_if_present (fn2, &fn2)) if (!get_global_value_if_present (fn2, &fn2))
fn2 = declare_nothrow_library_fn (fn2, ptr_type_node, fn2 = declare_library_fn (fn2, ptr_type_node,
ptr_type_node); ptr_type_node,
apply_tm_attr (fn2, get_identifier ("transaction_pure")); ECF_NOTHROW | ECF_TM_PURE | ECF_LEAF);
record_tm_replacement (fn, fn2); record_tm_replacement (fn, fn2);
} }
} }
...@@ -238,21 +240,17 @@ do_end_catch (tree type) ...@@ -238,21 +240,17 @@ do_end_catch (tree type)
fn = get_identifier ("__cxa_end_catch"); fn = get_identifier ("__cxa_end_catch");
if (!get_global_value_if_present (fn, &fn)) if (!get_global_value_if_present (fn, &fn))
{ {
/* Declare void __cxa_end_catch (). */ /* Declare void __cxa_end_catch ().
fn = push_void_library_fn (fn, void_list_node); This can throw if the destructor for the exception throws. */
/* This can throw if the destructor for the exception throws. */ fn = push_void_library_fn (fn, void_list_node, ECF_LEAF);
TREE_NOTHROW (fn) = 0;
/* Create its transactional-memory equivalent. */ /* Create its transactional-memory equivalent. */
if (flag_tm) if (flag_tm)
{ {
tree fn2 = get_identifier ("_ITM_cxa_end_catch"); tree fn2 = get_identifier ("_ITM_cxa_end_catch");
if (!get_global_value_if_present (fn2, &fn2)) if (!get_global_value_if_present (fn2, &fn2))
{ fn2 = push_void_library_fn (fn2, void_list_node,
fn2 = push_void_library_fn (fn2, void_list_node); ECF_TM_PURE | ECF_LEAF);
TREE_NOTHROW (fn2) = 0;
}
apply_tm_attr (fn2, get_identifier ("transaction_pure"));
record_tm_replacement (fn, fn2); record_tm_replacement (fn, fn2);
} }
} }
...@@ -631,15 +629,17 @@ do_allocate_exception (tree type) ...@@ -631,15 +629,17 @@ do_allocate_exception (tree type)
if (!get_global_value_if_present (fn, &fn)) if (!get_global_value_if_present (fn, &fn))
{ {
/* Declare void *__cxa_allocate_exception(size_t) throw(). */ /* 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) if (flag_tm)
{ {
tree fn2 = get_identifier ("_ITM_cxa_allocate_exception"); tree fn2 = get_identifier ("_ITM_cxa_allocate_exception");
if (!get_global_value_if_present (fn2, &fn2)) if (!get_global_value_if_present (fn2, &fn2))
fn2 = declare_nothrow_library_fn (fn2, ptr_type_node, fn2 = declare_library_fn (fn2, ptr_type_node,
size_type_node); size_type_node,
apply_tm_attr (fn2, get_identifier ("transaction_pure")); ECF_NOTHROW | ECF_MALLOC | ECF_TM_PURE
| ECF_LEAF);
record_tm_replacement (fn, fn2); record_tm_replacement (fn, fn2);
} }
} }
...@@ -660,7 +660,8 @@ do_free_exception (tree ptr) ...@@ -660,7 +660,8 @@ do_free_exception (tree ptr)
if (!get_global_value_if_present (fn, &fn)) if (!get_global_value_if_present (fn, &fn))
{ {
/* Declare void __cxa_free_exception (void *) throw(). */ /* 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); return cp_build_function_call_nary (fn, tf_warning_or_error, ptr, NULL_TREE);
......
...@@ -739,8 +739,8 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) ...@@ -739,8 +739,8 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
const_ptr_type_node, const_ptr_type_node,
tinfo_ptr, tinfo_ptr, tinfo_ptr, tinfo_ptr,
ptrdiff_type_node, NULL_TREE); ptrdiff_type_node, NULL_TREE);
dcast_fn = build_library_fn_ptr (name, tmp); dcast_fn = build_library_fn_ptr (name, tmp,
DECL_PURE_P (dcast_fn) = 1; ECF_LEAF | ECF_PURE | ECF_NOTHROW);
pop_abi_namespace (); pop_abi_namespace ();
dynamic_cast_node = dcast_fn; dynamic_cast_node = dcast_fn;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment