aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-08-16 10:06:14 +0200
committerMartin Liska <mliska@suse.cz>2022-08-16 10:06:14 +0200
commit091222fb0aaa09dcf90f2bc747f1d8a6a8ef1575 (patch)
tree07de02401c3374395a453724c4163d769c02e644 /gcc/cp
parentb629a7958faf817ef658e3ce59183bfb9ccefe96 (diff)
parent1c596391e150a6b0c55960c1c1cf1da76ea78230 (diff)
downloadgcc-091222fb0aaa09dcf90f2bc747f1d8a6a8ef1575.zip
gcc-091222fb0aaa09dcf90f2bc747f1d8a6a8ef1575.tar.gz
gcc-091222fb0aaa09dcf90f2bc747f1d8a6a8ef1575.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/decl.cc8
-rw-r--r--gcc/cp/typeck.cc31
3 files changed, 48 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ed83b97..f1c96b4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2022-08-15 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106276
+ * typeck.cc (can_do_rvo_p): New.
+ (maybe_warn_pessimizing_move): Warn when moving a temporary object
+ in a return statement prevents copy elision.
+
+2022-08-11 Marek Polacek <polacek@redhat.com>
+
+ PR middle-end/102633
+ * decl.cc (cp_finish_decl): Call suppress_warning.
+
2022-08-07 Jakub Jelinek <jakub@redhat.com>
PR c++/88174
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 70ad681..ff56fdd 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -8253,6 +8253,14 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
&& !TYPE_REF_P (type))
TREE_CONSTANT (decl) = 1;
}
+ /* This is handled mostly by gimplify.cc, but we have to deal with
+ not warning about int x = x; as it is a GCC extension to turn off
+ this warning but only if warn_init_self is zero. */
+ if (!DECL_EXTERNAL (decl)
+ && !TREE_STATIC (decl)
+ && decl == tree_strip_any_location_wrapper (init)
+ && !warn_init_self)
+ suppress_warning (decl, OPT_Winit_self);
}
if (flag_openmp
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 6e4f23a..15548e5 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -10287,12 +10287,29 @@ can_do_nrvo_p (tree retval, tree functype)
/* The cv-unqualified type of the returned value must be the
same as the cv-unqualified return type of the
function. */
- && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
- (TYPE_MAIN_VARIANT (functype)))
+ && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (retval)),
+ TYPE_MAIN_VARIANT (functype))
/* And the returned value must be non-volatile. */
&& !TYPE_VOLATILE (TREE_TYPE (retval)));
}
+/* Like can_do_nrvo_p, but we check if we're trying to move a class
+ prvalue. */
+
+static bool
+can_do_rvo_p (tree retval, tree functype)
+{
+ if (functype == error_mark_node)
+ return false;
+ if (retval)
+ STRIP_ANY_LOCATION_WRAPPER (retval);
+ return (retval != NULL_TREE
+ && !glvalue_p (retval)
+ && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (retval)),
+ TYPE_MAIN_VARIANT (functype))
+ && !TYPE_VOLATILE (TREE_TYPE (retval)));
+}
+
/* If we should treat RETVAL, an expression being returned, as if it were
designated by an rvalue, returns it adjusted accordingly; otherwise, returns
NULL_TREE. See [class.copy.elision]. RETURN_P is true if this is a return
@@ -10401,12 +10418,20 @@ maybe_warn_pessimizing_move (tree retval, tree functype)
"prevents copy elision"))
inform (loc, "remove %<std::move%> call");
}
+ else if (can_do_rvo_p (arg, functype))
+ {
+ auto_diagnostic_group d;
+ if (warning_at (loc, OPT_Wpessimizing_move,
+ "moving a temporary object in a return statement "
+ "prevents copy elision"))
+ inform (loc, "remove %<std::move%> call");
+ }
/* Warn if the move is redundant. It is redundant when we would
do maybe-rvalue overload resolution even without std::move. */
else if (warn_redundant_move
&& (moved = treat_lvalue_as_rvalue_p (arg, /*return*/true)))
{
- /* Make sure that the overload resolution would actually succeed
+ /* Make sure that overload resolution would actually succeed
if we removed the std::move call. */
tree t = convert_for_initialization (NULL_TREE, functype,
moved,