diff options
author | Jason Merrill <jason@redhat.com> | 2016-10-06 17:24:40 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-10-06 17:24:40 -0400 |
commit | b7558a2c1f87e374c48fa2be8e3ab93e1b3c68b0 (patch) | |
tree | c9167e38db4b5297835f67da69fdb6b691450d9f /gcc/cp/cvt.c | |
parent | 937ec71aba5b3c633bd5979d6346254e83f46d1c (diff) | |
download | gcc-b7558a2c1f87e374c48fa2be8e3ab93e1b3c68b0.zip gcc-b7558a2c1f87e374c48fa2be8e3ab93e1b3c68b0.tar.gz gcc-b7558a2c1f87e374c48fa2be8e3ab93e1b3c68b0.tar.bz2 |
C++17 copy elision improvements.
* call.c (build_temp, convert_like_real): Don't re-copy
TARGET_EXPR. Handle packed fields.
(build_x_va_arg): Wrap it in a TARGET_EXPR.
(build_over_call): Add sanity check.
* cvt.c (early_elide_copy): New.
(ocp_convert): Use it.
* except.c (build_throw): Use it.
* init.c (get_nsdmi): Put back the TARGET_EXPR.
(expand_default_init): Call early_elide_copy.
* typeck.c (cp_build_modify_expr): Call early_elide_copy.
From-SVN: r240845
Diffstat (limited to 'gcc/cp/cvt.c')
-rw-r--r-- | gcc/cp/cvt.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index ecc8ef8..063457f 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -658,6 +658,27 @@ cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain) return result; } +/* Returns true if we should avoid even doing overload resolution for copying + EXPR to initialize a TYPE. */ + +bool +early_elide_copy (tree type, tree expr) +{ + if (TREE_CODE (expr) != TARGET_EXPR) + return false; + /* List-initialization and direct-initialization don't involve a copy. */ + if (TARGET_EXPR_LIST_INIT_P (expr) + || TARGET_EXPR_DIRECT_INIT_P (expr)) + return true; + /* In C++17, "If the initializer expression is a prvalue and the + cv-unqualified version of the source type is the same class as the class + of the destination, the initializer expression is used to initialize the + destination object." */ + return (cxx_dialect >= cxx1z + && (same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (expr)))); +} + /* Conversion... FLAGS indicates how we should behave. */ @@ -694,10 +715,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags, return error_mark_node; if (MAYBE_CLASS_TYPE_P (type) && (convtype & CONV_FORCE_TEMP) - && !(cxx_dialect >= cxx1z - && TREE_CODE (e) == TARGET_EXPR)) - /* We need a new temporary; don't take this shortcut. But in C++17, don't - force a temporary if we already have one. */; + && !early_elide_copy (type, e)) + /* We need a new temporary; don't take this shortcut. */; else if (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (e))) { if (same_type_p (type, TREE_TYPE (e))) |