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
This commit is contained in:
Jan Hubicka 2013-08-30 10:14:37 +02:00 committed by Jan Hubicka
parent 47500756e5
commit fafa0521c9
6 changed files with 107 additions and 74 deletions

View File

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

View File

@ -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));

View File

@ -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);

View File

@ -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),

View File

@ -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);

View File

@ -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;
}