Commit 1a66d857 by Nathan Sidwell Committed by Nathan Sidwell

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
parent c405923d
2017-05-22 Nathan Sidwell <nathan@acm.org> 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, * name-lookup.c (pushdecl_top_level,
pushdecl_top_level_and_finish): Move after namespace pushing and pushdecl_top_level_and_finish): Move after namespace pushing and
popping functions. popping functions.
......
...@@ -150,7 +150,7 @@ genericize_eh_spec_block (tree *stmt_p) ...@@ -150,7 +150,7 @@ genericize_eh_spec_block (tree *stmt_p)
{ {
tree body = EH_SPEC_STMTS (*stmt_p); tree body = EH_SPEC_STMTS (*stmt_p);
tree allowed = EH_SPEC_RAISES (*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); *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
TREE_NO_WARNING (*stmt_p) = true; TREE_NO_WARNING (*stmt_p) = true;
...@@ -501,7 +501,7 @@ gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p) ...@@ -501,7 +501,7 @@ gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
gimple *mnt; gimple *mnt;
gimplify_and_add (body, &try_); 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); gimple_seq_add_stmt_without_update (&catch_, mnt);
mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH); mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
......
...@@ -153,8 +153,17 @@ enum cp_tree_index ...@@ -153,8 +153,17 @@ enum cp_tree_index
CPTI_EMPTY_EXCEPT_SPEC, CPTI_EMPTY_EXCEPT_SPEC,
CPTI_NOEXCEPT_TRUE_SPEC, CPTI_NOEXCEPT_TRUE_SPEC,
CPTI_NOEXCEPT_FALSE_SPEC, CPTI_NOEXCEPT_FALSE_SPEC,
CPTI_TERMINATE, CPTI_NOEXCEPT_DEFERRED_SPEC,
CPTI_CALL_UNEXPECTED,
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_FN_PTR_TYPE,
CPTI_ATEXIT, CPTI_ATEXIT,
CPTI_DSO_HANDLE, CPTI_DSO_HANDLE,
...@@ -242,17 +251,24 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; ...@@ -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_c cp_global_trees[CPTI_LANG_NAME_C]
#define lang_name_cplusplus cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS] #define lang_name_cplusplus cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS]
/* Exception specifiers used for throw(), noexcept(true) and /* Exception specifiers used for throw(), noexcept(true),
noexcept(false). We rely on these being uncloned. */ noexcept(false) and deferred noexcept. We rely on these being
uncloned. */
#define empty_except_spec cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC] #define empty_except_spec cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC]
#define noexcept_true_spec cp_global_trees[CPTI_NOEXCEPT_TRUE_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_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] /* Exception handling function declarations. */
#define terminate_fn cp_global_trees[CPTI_TERMINATE_FN]
/* The declaration for "__cxa_call_unexpected". */ #define call_unexpected_fn cp_global_trees[CPTI_CALL_UNEXPECTED_FN]
#define call_unexpected_node cp_global_trees[CPTI_CALL_UNEXPECTED] #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 /* The type of the function-pointer argument to "__cxa_atexit" (or
"std::atexit", if "__cxa_atexit" is not being used). */ "std::atexit", if "__cxa_atexit" is not being used). */
......
...@@ -42,15 +42,6 @@ static int complete_ptr_ref_or_void_ptr_p (tree, tree); ...@@ -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 bool is_admissible_throw_operand_or_catch_parameter (tree, bool);
static int can_convert_eh (tree, tree); 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 /* Sets up all the global eh stuff that needs to be initialized at the
start of compilation. */ start of compilation. */
...@@ -62,15 +53,15 @@ init_exception_processing (void) ...@@ -62,15 +53,15 @@ 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_fn = build_cp_library_fn_ptr ("terminate", tmp,
ECF_NOTHROW | ECF_NORETURN); ECF_NOTHROW | ECF_NORETURN);
TREE_THIS_VOLATILE (terminate_node) = 1; TREE_THIS_VOLATILE (terminate_fn) = 1;
TREE_NOTHROW (terminate_node) = 1; TREE_NOTHROW (terminate_fn) = 1;
pop_namespace (); pop_namespace ();
/* void __cxa_call_unexpected(void *); */ /* void __cxa_call_unexpected(void *); */
tmp = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE); 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); = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
} }
...@@ -84,7 +75,7 @@ cp_protect_cleanup_actions (void) ...@@ -84,7 +75,7 @@ cp_protect_cleanup_actions (void)
When the destruction of an object during stack unwinding exits When the destruction of an object during stack unwinding exits
using an exception ... void terminate(); is called. */ using an exception ... void terminate(); is called. */
return terminate_node; return terminate_fn;
} }
static tree static tree
...@@ -140,21 +131,39 @@ build_exc_ptr (void) ...@@ -140,21 +131,39 @@ build_exc_ptr (void)
1, integer_zero_node); 1, integer_zero_node);
} }
/* Declare a function NAME, returning RETURN_TYPE, taking a single /* Find or declare a function NAME, returning RTYPE, taking a single
parameter PARM_TYPE, with an empty exception specification. 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 Note that the C++ ABI document does not have a throw-specifier on
the routines declared below via this function. The declarations the routines declared below via this function. The declarations
are consistent with the actual implementations in libsupc++. */ are consistent with the actual implementations in libsupc++. */
static tree 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, tree ident = get_identifier (name);
parm_type, tree res = IDENTIFIER_GLOBAL_VALUE (ident);
NULL_TREE), if (!res)
empty_except_spec, {
ecf_flags); 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 /* 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) ...@@ -163,18 +172,16 @@ declare_library_fn (tree name, tree return_type, tree parm_type, int ecf_flags)
static tree static tree
do_get_exception_ptr (void) do_get_exception_ptr (void)
{ {
if (!fn1) if (!get_exception_ptr_fn)
{ /* Declare void* __cxa_get_exception_ptr (void *) throw(). */
tree name = get_identifier ("__cxa_get_exception_ptr"); get_exception_ptr_fn
fn1 = IDENTIFIER_GLOBAL_VALUE (name); = declare_library_fn ("__cxa_get_exception_ptr",
if (!fn1) ptr_type_node, ptr_type_node,
/* Declare void* __cxa_get_exception_ptr (void *) throw(). */ ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE,
fn1 = declare_library_fn 0);
(name, ptr_type_node, ptr_type_node,
ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE); return cp_build_function_call_nary (get_exception_ptr_fn,
} tf_warning_or_error,
return cp_build_function_call_nary (fn1, tf_warning_or_error,
build_exc_ptr (), NULL_TREE); build_exc_ptr (), NULL_TREE);
} }
...@@ -184,31 +191,14 @@ do_get_exception_ptr (void) ...@@ -184,31 +191,14 @@ do_get_exception_ptr (void)
static tree static tree
do_begin_catch (void) do_begin_catch (void)
{ {
if (!fn2) if (!begin_catch_fn)
{ /* Declare void* __cxa_begin_catch (void *) throw(). */
tree name = get_identifier ("__cxa_begin_catch"); begin_catch_fn
fn2 = IDENTIFIER_GLOBAL_VALUE (name); = declare_library_fn ("__cxa_begin_catch",
if (!fn2) ptr_type_node, ptr_type_node, ECF_NOTHROW,
{ ECF_TM_PURE);
/* Declare void* __cxa_begin_catch (void *) throw(). */
fn2 = declare_library_fn return cp_build_function_call_nary (begin_catch_fn, tf_warning_or_error,
(name, ptr_type_node, ptr_type_node, ECF_NOTHROW);
/* 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,
build_exc_ptr (), NULL_TREE); build_exc_ptr (), NULL_TREE);
} }
...@@ -236,30 +226,15 @@ dtor_nothrow (tree type) ...@@ -236,30 +226,15 @@ dtor_nothrow (tree type)
static tree static tree
do_end_catch (tree type) do_end_catch (tree type)
{ {
if (!fn3) if (!end_catch_fn)
{ /* Declare void __cxa_end_catch ().
tree name = get_identifier ("__cxa_end_catch"); This can throw if the destructor for the exception throws. */
fn3 = IDENTIFIER_GLOBAL_VALUE (name); end_catch_fn
if (!fn3) = declare_library_fn ("__cxa_end_catch", void_type_node,
{ NULL_TREE, 0, ECF_TM_PURE);
/* Declare void __cxa_end_catch ().
This can throw if the destructor for the exception throws. */ tree cleanup = cp_build_function_call_vec (end_catch_fn,
fn3 = push_void_library_fn (name, void_list_node, 0); NULL, tf_warning_or_error);
/* 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_NOTHROW (cleanup) = dtor_nothrow (type); TREE_NOTHROW (cleanup) = dtor_nothrow (type);
return cleanup; return cleanup;
...@@ -519,30 +494,15 @@ finish_eh_spec_block (tree raw_raises, tree eh_spec_block) ...@@ -519,30 +494,15 @@ finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
static tree static tree
do_allocate_exception (tree type) do_allocate_exception (tree type)
{ {
if (!fn4) if (!allocate_exception_fn)
{ /* Declare void *__cxa_allocate_exception(size_t) throw(). */
tree name = get_identifier ("__cxa_allocate_exception"); allocate_exception_fn
fn4 = IDENTIFIER_GLOBAL_VALUE (name); = declare_library_fn ("__cxa_allocate_exception",
if (!fn4) ptr_type_node, size_type_node,
{ ECF_NOTHROW | ECF_MALLOC, ECF_TM_PURE);
/* Declare void *__cxa_allocate_exception(size_t) throw(). */
fn4 = declare_library_fn (name, ptr_type_node, size_type_node, return cp_build_function_call_nary (allocate_exception_fn,
ECF_NOTHROW | ECF_MALLOC); tf_warning_or_error,
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,
size_in_bytes (type), NULL_TREE); size_in_bytes (type), NULL_TREE);
} }
...@@ -552,30 +512,15 @@ do_allocate_exception (tree type) ...@@ -552,30 +512,15 @@ do_allocate_exception (tree type)
static tree static tree
do_free_exception (tree ptr) do_free_exception (tree ptr)
{ {
if (!fn5) if (!free_exception_fn)
{ /* Declare void __cxa_free_exception (void *) throw(). */
tree name = get_identifier ("__cxa_free_exception"); free_exception_fn
fn5 = IDENTIFIER_GLOBAL_VALUE (name); = declare_library_fn ("__cxa_free_exception",
if (!fn5) void_type_node, ptr_type_node,
{ ECF_NOTHROW | ECF_LEAF, ECF_TM_PURE);
/* Declare void __cxa_free_exception (void *) throw(). */
fn5 = declare_library_fn (name, void_type_node, ptr_type_node, return cp_build_function_call_nary (free_exception_fn,
ECF_NOTHROW | ECF_LEAF); tf_warning_or_error, ptr, NULL_TREE);
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);
} }
/* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR. /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
...@@ -1257,9 +1202,10 @@ build_noexcept_spec (tree expr, int complain) ...@@ -1257,9 +1202,10 @@ build_noexcept_spec (tree expr, int complain)
tree tree
unevaluated_noexcept_spec (void) unevaluated_noexcept_spec (void)
{ {
if (spec == NULL_TREE) if (!noexcept_deferred_spec)
spec = build_noexcept_spec (make_node (DEFERRED_NOEXCEPT), tf_none); noexcept_deferred_spec
return 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 /* Returns a TRY_CATCH_EXPR that will put TRY_LIST and CATCH_LIST in the
......
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