static void make_rtl_for_nonlocal_decl (tree, tree, const char *);
static void copy_type_enum (tree , tree);
static void check_function_type (tree, tree);
-static void finish_constructor_body (void);
static void begin_destructor_body (void);
-static void finish_destructor_body (void);
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);
}
\f
-/* Set the return value of the constructor (if present). */
+/* Set the return value of the [cd]tor if the ABI wants that. */
-static void
-finish_constructor_body (void)
+void
+maybe_return_this (void)
{
- tree val;
- tree exprstmt;
-
if (targetm.cxx.cdtor_returns_this ())
{
- val = DECL_ARGUMENTS (current_function_decl);
+ /* Return the address of the object. */
+ tree val = DECL_ARGUMENTS (current_function_decl);
suppress_warning (val, OPT_Wuse_after_free);
+ val = fold_convert (TREE_TYPE (DECL_RESULT (current_function_decl)), val);
val = build2 (MODIFY_EXPR, TREE_TYPE (val),
DECL_RESULT (current_function_decl), val);
- /* Return the address of the object. */
- exprstmt = build_stmt (input_location, RETURN_EXPR, val);
+ tree exprstmt = build_stmt (input_location, RETURN_EXPR, val);
add_stmt (exprstmt);
}
}
}
}
-/* At the end of every destructor we generate code to delete the object if
- necessary. Do that now. */
-
-static void
-finish_destructor_body (void)
-{
- tree exprstmt;
-
- if (targetm.cxx.cdtor_returns_this ())
- {
- tree val;
-
- val = DECL_ARGUMENTS (current_function_decl);
- suppress_warning (val, OPT_Wuse_after_free);
- val = build2 (MODIFY_EXPR, TREE_TYPE (val),
- DECL_RESULT (current_function_decl), val);
- /* Return the address of the object. */
- exprstmt = build_stmt (input_location, RETURN_EXPR, val);
- add_stmt (exprstmt);
- }
-}
-
/* Do the necessary processing for the beginning of a function body, which
in this case includes member-initializers, but not the catch clauses of
a function-try-block. Currently, this means opening a binding level
if (processing_template_decl)
/* Do nothing now. */;
- else if (DECL_CONSTRUCTOR_P (current_function_decl))
- finish_constructor_body ();
- else if (DECL_DESTRUCTOR_P (current_function_decl))
- finish_destructor_body ();
+ else if (DECL_CONSTRUCTOR_P (current_function_decl)
+ || DECL_DESTRUCTOR_P (current_function_decl))
+ maybe_return_this ();
}
/* Given a function, returns the BLOCK corresponding to the outermost level
/* Return the address of the object.
??? How is it useful to return an invalid address? */
- if (targetm.cxx.cdtor_returns_this ())
- {
- tree val = DECL_ARGUMENTS (delete_dtor);
- suppress_warning (val, OPT_Wuse_after_free);
- val = build2 (MODIFY_EXPR, TREE_TYPE (val),
- DECL_RESULT (delete_dtor), val);
- add_stmt (build_stmt (0, RETURN_EXPR, val));
- }
+ maybe_return_this ();
}
/* Return name of comdat group for complete and base ctor (or dtor)