aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/semantics.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r--gcc/cp/semantics.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 9dddf23..0dc392a 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -49,6 +49,7 @@
static tree maybe_convert_cond PARAMS ((tree));
static tree simplify_aggr_init_exprs_r PARAMS ((tree *, int *, void *));
+static tree nullify_returns_r PARAMS ((tree *, int *, void *));
static void deferred_type_access_control PARAMS ((void));
static void emit_associated_thunks PARAMS ((tree));
static void genrtl_try_block PARAMS ((tree));
@@ -2464,6 +2465,25 @@ expand_body (fn)
timevar_pop (TV_EXPAND);
}
+/* Helper function for walk_tree, used by genrtl_start_function to override
+ all the RETURN_STMTs for the named return value optimization. */
+
+static tree
+nullify_returns_r (tp, walk_subtrees, data)
+ tree *tp;
+ int *walk_subtrees;
+ void *data ATTRIBUTE_UNUSED;
+{
+ /* No need to walk into types. */
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ else if (TREE_CODE (*tp) == RETURN_STMT)
+ RETURN_NULLIFIED_P (*tp) = 1;
+
+ /* Keep iterating. */
+ return NULL_TREE;
+}
+
/* Start generating the RTL for FN. */
static void
@@ -2541,6 +2561,22 @@ genrtl_start_function (fn)
/* Create a binding contour which can be used to catch
cleanup-generated temporaries. */
expand_start_bindings (2);
+
+ /* Set up the named return value optimization, if we can. */
+ if (current_function_return_value
+ && current_function_return_value != error_mark_node)
+ {
+ tree r = current_function_return_value;
+ /* This is only worth doing for fns that return in memory--and
+ simpler, since we don't have to worry about promoted modes. */
+ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (fn))))
+ {
+ COPY_DECL_RTL (DECL_RESULT (fn), r);
+ DECL_ALIGN (r) = DECL_ALIGN (DECL_RESULT (fn));
+ walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
+ nullify_returns_r, NULL_TREE);
+ }
+ }
}
/* Finish generating the RTL for FN. */
@@ -2579,7 +2615,6 @@ genrtl_finish_function (fn)
if (!dtor_label && !DECL_CONSTRUCTOR_P (fn)
&& return_label != NULL_RTX
- && current_function_return_value == NULL_TREE
&& ! DECL_NAME (DECL_RESULT (current_function_decl)))
no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);