aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/cp-tree.h7
-rw-r--r--gcc/cp/decl.cc59
-rw-r--r--gcc/cp/except.cc6
3 files changed, 38 insertions, 34 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index db098c3..07e9632 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -368,8 +368,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
#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). */
+/* The type of the function-pointer argument to "std::atexit". */
#define atexit_fn_ptr_type_node cp_global_trees[CPTI_ATEXIT_FN_PTR_TYPE]
/* A pointer to `std::atexit'. */
@@ -384,7 +383,8 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
/* The declaration of the dynamic_cast runtime. */
#define dynamic_cast_node cp_global_trees[CPTI_DCAST]
-/* The type of a destructor. */
+/* The type of a destructor, passed to __cxa_atexit, __cxa_thread_atexit
+ or __cxa_throw. */
#define cleanup_type cp_global_trees[CPTI_CLEANUP_TYPE]
/* The type of the vtt parameter passed to subobject constructors and
@@ -7067,6 +7067,7 @@ extern tree check_default_argument (tree, tree, tsubst_flags_t);
extern int wrapup_namespace_globals ();
extern tree create_implicit_typedef (tree, tree);
extern int local_variable_p (const_tree);
+extern tree get_cxa_atexit_fn_ptr_type ();
extern tree register_dtor_fn (tree);
extern tmpl_spec_kind current_tmpl_spec_kind (int);
extern tree cxx_builtin_function (tree decl);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index e025624..3fc8835 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -93,7 +93,7 @@ static void record_key_method_defined (tree);
static tree create_array_type_for_decl (tree, tree, tree, location_t);
static tree get_atexit_node (void);
static tree get_dso_handle_node (void);
-static tree start_cleanup_fn (void);
+static tree start_cleanup_fn (bool);
static void end_cleanup_fn (void);
static tree cp_make_fname_decl (location_t, tree, int);
static void initialize_predefined_identifiers (void);
@@ -9678,34 +9678,39 @@ declare_global_var (tree name, tree type)
return decl;
}
-/* Returns the type for the argument to "__cxa_atexit" (or "atexit",
- if "__cxa_atexit" is not being used) corresponding to the function
+/* Returns the type for the argument to "atexit" corresponding to the function
to be called when the program exits. */
static tree
-get_atexit_fn_ptr_type (void)
+get_atexit_fn_ptr_type ()
{
- tree fn_type;
-
if (!atexit_fn_ptr_type_node)
{
- tree arg_type;
- if (flag_use_cxa_atexit
- && !targetm.cxx.use_atexit_for_cxa_atexit ())
- /* The parameter to "__cxa_atexit" is "void (*)(void *)". */
- arg_type = ptr_type_node;
- else
- /* The parameter to "atexit" is "void (*)(void)". */
- arg_type = NULL_TREE;
-
- fn_type = build_function_type_list (void_type_node,
- arg_type, NULL_TREE);
+ tree fn_type = build_function_type_list (void_type_node, NULL_TREE);
atexit_fn_ptr_type_node = build_pointer_type (fn_type);
}
return atexit_fn_ptr_type_node;
}
+/* Returns the type for the argument to "__cxa_atexit", "__cxa_thread_atexit"
+ or "__cxa_throw" corresponding to the destructor to be called when the
+ program exits. */
+
+tree
+get_cxa_atexit_fn_ptr_type ()
+{
+ if (!cleanup_type)
+ {
+ tree fntype = build_function_type_list (void_type_node,
+ ptr_type_node, NULL_TREE);
+ fntype = targetm.cxx.adjust_cdtor_callabi_fntype (fntype);
+ cleanup_type = build_pointer_type (fntype);
+ }
+
+ return cleanup_type;
+}
+
/* Returns a pointer to the `atexit' function. Note that if
FLAG_USE_CXA_ATEXIT is nonzero, then this will actually be the new
`__cxa_atexit' function specified in the IA64 C++ ABI. */
@@ -9736,7 +9741,7 @@ get_atexit_node (void)
use_aeabi_atexit = targetm.cxx.use_aeabi_atexit ();
/* First, build the pointer-to-function type for the first
argument. */
- fn_ptr_type = get_atexit_fn_ptr_type ();
+ fn_ptr_type = get_cxa_atexit_fn_ptr_type ();
/* Then, build the rest of the argument types. */
argtype2 = ptr_type_node;
if (use_aeabi_atexit)
@@ -9819,7 +9824,7 @@ get_thread_atexit_node (void)
int __cxa_thread_atexit (void (*)(void *), void *, void *) */
tree fn_type = build_function_type_list (integer_type_node,
- get_atexit_fn_ptr_type (),
+ get_cxa_atexit_fn_ptr_type (),
ptr_type_node, ptr_type_node,
NULL_TREE);
@@ -9861,12 +9866,13 @@ get_dso_handle_node (void)
}
/* Begin a new function with internal linkage whose job will be simply
- to destroy some particular variable. */
+ to destroy some particular variable. OB_PARM is true if object pointer
+ is passed to the cleanup function, otherwise no argument is passed. */
static GTY(()) int start_cleanup_cnt;
static tree
-start_cleanup_fn (void)
+start_cleanup_fn (bool ob_parm)
{
char name[32];
@@ -9877,8 +9883,9 @@ start_cleanup_fn (void)
/* Build the name of the function. */
sprintf (name, "__tcf_%d", start_cleanup_cnt++);
+ tree fntype = TREE_TYPE (ob_parm ? get_cxa_atexit_fn_ptr_type ()
+ : get_atexit_fn_ptr_type ());
/* Build the function declaration. */
- tree fntype = TREE_TYPE (get_atexit_fn_ptr_type ());
tree fndecl = build_lang_decl (FUNCTION_DECL, get_identifier (name), fntype);
DECL_CONTEXT (fndecl) = FROB_CONTEXT (current_namespace);
/* It's a function with internal linkage, generated by the
@@ -9891,7 +9898,7 @@ start_cleanup_fn (void)
emissions this way. */
DECL_DECLARED_INLINE_P (fndecl) = 1;
DECL_INTERFACE_KNOWN (fndecl) = 1;
- if (flag_use_cxa_atexit && !targetm.cxx.use_atexit_for_cxa_atexit ())
+ if (ob_parm)
{
/* Build the parameter. */
tree parmdecl = cp_build_parm_decl (fndecl, NULL_TREE, ptr_type_node);
@@ -9968,8 +9975,8 @@ register_dtor_fn (tree decl)
build_cleanup (decl);
/* Now start the function. */
- cleanup = start_cleanup_fn ();
-
+ cleanup = start_cleanup_fn (ob_parm);
+
/* Now, recompute the cleanup. It may contain SAVE_EXPRs that refer
to the original function, rather than the anonymous one. That
will make the back end think that nested functions are in use,
@@ -9998,7 +10005,7 @@ register_dtor_fn (tree decl)
{
/* We must convert CLEANUP to the type that "__cxa_atexit"
expects. */
- cleanup = build_nop (get_atexit_fn_ptr_type (), cleanup);
+ cleanup = build_nop (get_cxa_atexit_fn_ptr_type (), cleanup);
/* "__cxa_atexit" will pass the address of DECL to the
cleanup function. */
mark_used (decl);
diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc
index f1ffda22..1eb3ba5 100644
--- a/gcc/cp/except.cc
+++ b/gcc/cp/except.cc
@@ -645,11 +645,7 @@ build_throw (location_t loc, tree exp, tsubst_flags_t complain)
/* The CLEANUP_TYPE is the internal type of a destructor. */
if (!cleanup_type)
- {
- tree tmp = build_function_type_list (void_type_node,
- ptr_type_node, NULL_TREE);
- cleanup_type = build_pointer_type (tmp);
- }
+ cleanup_type = get_cxa_atexit_fn_ptr_type ();
if (!throw_fn)
{