summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog39
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-tree.h8
-rw-r--r--gcc/cp/decl.c77
-rw-r--r--gcc/cp/except.c51
-rw-r--r--gcc/cp/rtti.c4
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;
}