cp-tree.h (CPTI_TERMINATE, [...]): Rename to ...

* cp-tree.h (CPTI_TERMINATE, CPTI_CALL_UNEXPECTED): Rename to ...
	(CPTI_TERMINATE_FN, CPTI_CALL_UNEXPECTED_FN): ... here.
	( CPTI_GET_EXCEPTION_PTR_FN, CPTI_BEGIN_CATCH_FN)
	(CPTI_END_CATCH_FN)
	CPTI_ALLOCATE_EXCEPTION_FN, CPTI_FREE_EXCEPTION_FN, CPTI_THROW_FN,
	CPTI_RETHROW_FN): New.
	(noexcept_deferred_spec): New.
	(terminate_node, call_unexpected_node): Rename to ...
	(terminate_fn, call_unexpected_fn): ... here.
	(get_exception_ptr_fn, begin_catch_fn, end_catch_fn)
	allocate_exception_fn, free_exception_fn, throw_fn, rethrow_fn):
	New.
	* except.c (fn1..fn5, throw_fn, rethrow_rn, spec): Delete.
	(init_exception_processing): Adjust.
	(declare_library_fn): Create and push the fns here.
	(do_get_exception_ptr, do_begin_catch, do_end_catch)
	do_allocate_exception_ptr, do_free_exception_ptr): Adjust
	declare_library_fn use.
	(unevaluated_noexcept_spec): Adjust.
	* cp-gimplify.c (genericize_eh_spec_block)
	gimplify_most_not_throw_expr): Adjust.
((((--This line, and those below, will be ignored--

M    cp/cp-tree.h
M    cp/ChangeLog
M    cp/cp-gimplify.c
M    cp/except.c

From-SVN: r248328
This commit is contained in:
Nathan Sidwell 2017-05-22 11:32:16 +00:00 committed by Nathan Sidwell
parent c405923d02
commit 1a66d857e6
4 changed files with 122 additions and 140 deletions

View file

@ -1,5 +1,25 @@
2017-05-22 Nathan Sidwell <nathan@acm.org>
* cp-tree.h (CPTI_TERMINATE, CPTI_CALL_UNEXPECTED): Rename to ...
(CPTI_TERMINATE_FN, CPTI_CALL_UNEXPECTED_FN): ... here.
( CPTI_GET_EXCEPTION_PTR_FN, CPTI_BEGIN_CATCH_FN, CPTI_END_CATCH_FN,
CPTI_ALLOCATE_EXCEPTION_FN, CPTI_FREE_EXCEPTION_FN, CPTI_THROW_FN,
CPTI_RETHROW_FN): New.
(noexcept_deferred_spec): New.
(terminate_node, call_unexpected_node): Rename to ...
(terminate_fn, call_unexpected_fn): ... here.
(get_exception_ptr_fn, begin_catch_fn, end_catch_fn,
allocate_exception_fn, free_exception_fn, throw_fn, rethrow_fn): New.
* except.c (fn1..fn5, throw_fn, rethrow_rn, spec): Delete.
(init_exception_processing): Adjust.
(declare_library_fn): Create and push the fns here.
(do_get_exception_ptr, do_begin_catch, do_end_catch,
do_allocate_exception_ptr, do_free_exception_ptr): Adjust
declare_library_fn use.
(unevaluated_noexcept_spec): Adjust.
* cp-gimplify.c (genericize_eh_spec_block,
gimplify_most_not_throw_expr): Adjust.
* name-lookup.c (pushdecl_top_level,
pushdecl_top_level_and_finish): Move after namespace pushing and
popping functions.

View file

@ -150,7 +150,7 @@ genericize_eh_spec_block (tree *stmt_p)
{
tree body = EH_SPEC_STMTS (*stmt_p);
tree allowed = EH_SPEC_RAISES (*stmt_p);
tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
tree failure = build_call_n (call_unexpected_fn, 1, build_exc_ptr ());
*stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
TREE_NO_WARNING (*stmt_p) = true;
@ -501,7 +501,7 @@ gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
gimple *mnt;
gimplify_and_add (body, &try_);
mnt = gimple_build_eh_must_not_throw (terminate_node);
mnt = gimple_build_eh_must_not_throw (terminate_fn);
gimple_seq_add_stmt_without_update (&catch_, mnt);
mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);

View file

@ -153,8 +153,17 @@ enum cp_tree_index
CPTI_EMPTY_EXCEPT_SPEC,
CPTI_NOEXCEPT_TRUE_SPEC,
CPTI_NOEXCEPT_FALSE_SPEC,
CPTI_TERMINATE,
CPTI_CALL_UNEXPECTED,
CPTI_NOEXCEPT_DEFERRED_SPEC,
CPTI_TERMINATE_FN,
CPTI_CALL_UNEXPECTED_FN,
CPTI_GET_EXCEPTION_PTR_FN,
CPTI_BEGIN_CATCH_FN,
CPTI_END_CATCH_FN,
CPTI_ALLOCATE_EXCEPTION_FN,
CPTI_FREE_EXCEPTION_FN,
CPTI_THROW_FN,
CPTI_RETHROW_FN,
CPTI_ATEXIT_FN_PTR_TYPE,
CPTI_ATEXIT,
CPTI_DSO_HANDLE,
@ -242,17 +251,24 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
#define lang_name_c cp_global_trees[CPTI_LANG_NAME_C]
#define lang_name_cplusplus cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS]
/* Exception specifiers used for throw(), noexcept(true) and
noexcept(false). We rely on these being uncloned. */
/* Exception specifiers used for throw(), noexcept(true),
noexcept(false) and deferred noexcept. We rely on these being
uncloned. */
#define empty_except_spec cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC]
#define noexcept_true_spec cp_global_trees[CPTI_NOEXCEPT_TRUE_SPEC]
#define noexcept_false_spec cp_global_trees[CPTI_NOEXCEPT_FALSE_SPEC]
#define noexcept_deferred_spec cp_global_trees[CPTI_NOEXCEPT_DEFERRED_SPEC]
/* The declaration for `std::terminate'. */
#define terminate_node cp_global_trees[CPTI_TERMINATE]
/* The declaration for "__cxa_call_unexpected". */
#define call_unexpected_node cp_global_trees[CPTI_CALL_UNEXPECTED]
/* Exception handling function declarations. */
#define terminate_fn cp_global_trees[CPTI_TERMINATE_FN]
#define call_unexpected_fn cp_global_trees[CPTI_CALL_UNEXPECTED_FN]
#define get_exception_ptr_fn cp_global_trees[CPTI_GET_EXCEPTION_PTR_FN]
#define begin_catch_fn cp_global_trees[CPTI_BEGIN_CATCH_FN]
#define end_catch_fn cp_global_trees[CPTI_END_CATCH_FN]
#define allocate_exception_fn cp_global_trees[CPTI_ALLOCATE_EXCEPTION_FN]
#define free_exception_fn cp_global_trees[CPTI_FREE_EXCEPTION_FN]
#define throw_fn cp_global_trees[CPTI_THROW_FN]
#define rethrow_fn cp_global_trees[CPTI_RETHROW_FN]
/* The type of the function-pointer argument to "__cxa_atexit" (or
"std::atexit", if "__cxa_atexit" is not being used). */

View file

@ -42,15 +42,6 @@ static int complete_ptr_ref_or_void_ptr_p (tree, tree);
static bool is_admissible_throw_operand_or_catch_parameter (tree, bool);
static int can_convert_eh (tree, tree);
static GTY(()) tree fn1;
static GTY(()) tree fn2;
static GTY(()) tree fn3;
static GTY(()) tree fn4;
static GTY(()) tree fn5;
static GTY(()) tree throw_fn;
static GTY(()) tree rethrow_fn;
static GTY(()) tree spec;
/* Sets up all the global eh stuff that needs to be initialized at the
start of compilation. */
@ -62,15 +53,15 @@ 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_fn = build_cp_library_fn_ptr ("terminate", tmp,
ECF_NOTHROW | ECF_NORETURN);
TREE_THIS_VOLATILE (terminate_node) = 1;
TREE_NOTHROW (terminate_node) = 1;
TREE_THIS_VOLATILE (terminate_fn) = 1;
TREE_NOTHROW (terminate_fn) = 1;
pop_namespace ();
/* void __cxa_call_unexpected(void *); */
tmp = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
call_unexpected_node
call_unexpected_fn
= push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
}
@ -84,7 +75,7 @@ cp_protect_cleanup_actions (void)
When the destruction of an object during stack unwinding exits
using an exception ... void terminate(); is called. */
return terminate_node;
return terminate_fn;
}
static tree
@ -140,21 +131,39 @@ build_exc_ptr (void)
1, integer_zero_node);
}
/* Declare a function NAME, returning RETURN_TYPE, taking a single
parameter PARM_TYPE, with an empty exception specification.
/* Find or declare a function NAME, returning RTYPE, taking a single
parameter PTYPE, with an empty exception specification. ECF are the
library fn flags. If TM_ECF is non-zero, also find or create a
transaction variant and record it as a replacement, when flag_tm is
in effect.
Note that the C++ ABI document does not have a throw-specifier on
the routines declared below via this function. The declarations
are consistent with the actual implementations in libsupc++. */
static tree
declare_library_fn (tree name, tree return_type, tree parm_type, int ecf_flags)
declare_library_fn (const char *name, tree rtype, tree ptype,
int ecf, int tm_ecf)
{
return push_library_fn (name, build_function_type_list (return_type,
parm_type,
NULL_TREE),
empty_except_spec,
ecf_flags);
tree ident = get_identifier (name);
tree res = IDENTIFIER_GLOBAL_VALUE (ident);
if (!res)
{
tree type = build_function_type_list (rtype, ptype, NULL_TREE);
tree except = ecf & ECF_NOTHROW ? empty_except_spec : NULL_TREE;
res = push_library_fn (ident, type, except, ecf);
if (tm_ecf && flag_tm)
{
char *tm_name = concat ("_ITM_", name + 2, NULL_TREE);
tree tm_ident = get_identifier (tm_name);
free (tm_name);
tree tm_fn = IDENTIFIER_GLOBAL_VALUE (tm_ident);
if (!tm_fn)
tm_fn = push_library_fn (tm_ident, type, except, ecf | tm_ecf);
record_tm_replacement (res, tm_fn);
}
}
return res;
}
/* Build up a call to __cxa_get_exception_ptr so that we can build a
@ -163,18 +172,16 @@ declare_library_fn (tree name, tree return_type, tree parm_type, int ecf_flags)
static tree
do_get_exception_ptr (void)
{
if (!fn1)
{
tree name = get_identifier ("__cxa_get_exception_ptr");
fn1 = IDENTIFIER_GLOBAL_VALUE (name);
if (!fn1)
/* Declare void* __cxa_get_exception_ptr (void *) throw(). */
fn1 = declare_library_fn
(name, ptr_type_node, ptr_type_node,
ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE);
}
if (!get_exception_ptr_fn)
/* Declare void* __cxa_get_exception_ptr (void *) throw(). */
get_exception_ptr_fn
= declare_library_fn ("__cxa_get_exception_ptr",
ptr_type_node, ptr_type_node,
ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE,
0);
return cp_build_function_call_nary (fn1, tf_warning_or_error,
return cp_build_function_call_nary (get_exception_ptr_fn,
tf_warning_or_error,
build_exc_ptr (), NULL_TREE);
}
@ -184,31 +191,14 @@ do_get_exception_ptr (void)
static tree
do_begin_catch (void)
{
if (!fn2)
{
tree name = get_identifier ("__cxa_begin_catch");
fn2 = IDENTIFIER_GLOBAL_VALUE (name);
if (!fn2)
{
/* Declare void* __cxa_begin_catch (void *) throw(). */
fn2 = declare_library_fn
(name, ptr_type_node, ptr_type_node, ECF_NOTHROW);
if (!begin_catch_fn)
/* Declare void* __cxa_begin_catch (void *) throw(). */
begin_catch_fn
= declare_library_fn ("__cxa_begin_catch",
ptr_type_node, ptr_type_node, ECF_NOTHROW,
ECF_TM_PURE);
/* Create its transactional-memory equivalent. */
if (flag_tm)
{
tree itm_name = get_identifier ("_ITM_cxa_begin_catch");
tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name);
if (!itm_fn)
itm_fn = declare_library_fn
(itm_name, ptr_type_node, ptr_type_node,
ECF_NOTHROW | ECF_TM_PURE);
record_tm_replacement (fn2, itm_fn);
}
}
}
return cp_build_function_call_nary (fn2, tf_warning_or_error,
return cp_build_function_call_nary (begin_catch_fn, tf_warning_or_error,
build_exc_ptr (), NULL_TREE);
}
@ -236,30 +226,15 @@ dtor_nothrow (tree type)
static tree
do_end_catch (tree type)
{
if (!fn3)
{
tree name = get_identifier ("__cxa_end_catch");
fn3 = IDENTIFIER_GLOBAL_VALUE (name);
if (!fn3)
{
/* Declare void __cxa_end_catch ().
This can throw if the destructor for the exception throws. */
fn3 = push_void_library_fn (name, void_list_node, 0);
if (!end_catch_fn)
/* Declare void __cxa_end_catch ().
This can throw if the destructor for the exception throws. */
end_catch_fn
= declare_library_fn ("__cxa_end_catch", void_type_node,
NULL_TREE, 0, ECF_TM_PURE);
/* Create its transactional-memory equivalent. */
if (flag_tm)
{
tree itm_name = get_identifier ("_ITM_cxa_end_catch");
tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name);
if (!itm_fn)
itm_fn = push_void_library_fn
(itm_name, void_list_node, ECF_TM_PURE);
record_tm_replacement (fn3, itm_fn);
}
}
}
tree cleanup = cp_build_function_call_vec (fn3, NULL, tf_warning_or_error);
tree cleanup = cp_build_function_call_vec (end_catch_fn,
NULL, tf_warning_or_error);
TREE_NOTHROW (cleanup) = dtor_nothrow (type);
return cleanup;
@ -519,30 +494,15 @@ finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
static tree
do_allocate_exception (tree type)
{
if (!fn4)
{
tree name = get_identifier ("__cxa_allocate_exception");
fn4 = IDENTIFIER_GLOBAL_VALUE (name);
if (!fn4)
{
/* Declare void *__cxa_allocate_exception(size_t) throw(). */
fn4 = declare_library_fn (name, ptr_type_node, size_type_node,
ECF_NOTHROW | ECF_MALLOC);
if (!allocate_exception_fn)
/* Declare void *__cxa_allocate_exception(size_t) throw(). */
allocate_exception_fn
= declare_library_fn ("__cxa_allocate_exception",
ptr_type_node, size_type_node,
ECF_NOTHROW | ECF_MALLOC, ECF_TM_PURE);
if (flag_tm)
{
tree itm_name = get_identifier ("_ITM_cxa_allocate_exception");
tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name);
if (!itm_fn)
itm_fn = declare_library_fn
(itm_name, ptr_type_node, size_type_node,
ECF_NOTHROW | ECF_MALLOC | ECF_TM_PURE);
record_tm_replacement (fn4, itm_fn);
}
}
}
return cp_build_function_call_nary (fn4, tf_warning_or_error,
return cp_build_function_call_nary (allocate_exception_fn,
tf_warning_or_error,
size_in_bytes (type), NULL_TREE);
}
@ -552,30 +512,15 @@ do_allocate_exception (tree type)
static tree
do_free_exception (tree ptr)
{
if (!fn5)
{
tree name = get_identifier ("__cxa_free_exception");
fn5 = IDENTIFIER_GLOBAL_VALUE (name);
if (!fn5)
{
/* Declare void __cxa_free_exception (void *) throw(). */
fn5 = declare_library_fn (name, void_type_node, ptr_type_node,
ECF_NOTHROW | ECF_LEAF);
if (!free_exception_fn)
/* Declare void __cxa_free_exception (void *) throw(). */
free_exception_fn
= declare_library_fn ("__cxa_free_exception",
void_type_node, ptr_type_node,
ECF_NOTHROW | ECF_LEAF, ECF_TM_PURE);
if (flag_tm)
{
tree itm_name = get_identifier ("_ITM_cxa_free_exception");
tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name);
if (!itm_fn)
itm_fn = declare_library_fn
(itm_name, void_type_node, ptr_type_node,
ECF_NOTHROW | ECF_LEAF | ECF_TM_PURE);
record_tm_replacement (fn5, itm_fn);
}
}
}
return cp_build_function_call_nary (fn5, tf_warning_or_error, ptr, NULL_TREE);
return cp_build_function_call_nary (free_exception_fn,
tf_warning_or_error, ptr, NULL_TREE);
}
/* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
@ -1257,9 +1202,10 @@ build_noexcept_spec (tree expr, int complain)
tree
unevaluated_noexcept_spec (void)
{
if (spec == NULL_TREE)
spec = build_noexcept_spec (make_node (DEFERRED_NOEXCEPT), tf_none);
return spec;
if (!noexcept_deferred_spec)
noexcept_deferred_spec
= build_noexcept_spec (make_node (DEFERRED_NOEXCEPT), tf_none);
return noexcept_deferred_spec;
}
/* Returns a TRY_CATCH_EXPR that will put TRY_LIST and CATCH_LIST in the