public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-7069] c++: assignment, aggregate, array [PR104300]
@ 2022-02-05 5:57 Jason Merrill
0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2022-02-05 5:57 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:119cea98f664764cce04963243c39c8f6d797d33
commit r12-7069-g119cea98f664764cce04963243c39c8f6d797d33
Author: Jason Merrill <jason@redhat.com>
Date: Wed Feb 2 18:36:41 2022 -0500
c++: assignment, aggregate, array [PR104300]
The PR92385 fix meant that we see more VEC_INIT_EXPR outside of INIT_EXPR;
in such cases, we need to wrap them in TARGET_EXPR. I previously fixed
that in build_array_copy; we also need it in process_init_constructor.
After fixing that, I needed to adjust a few places to recognize the
VEC_INIT_EXPR even inside a TARGET_EXPR. And prevent cp_fully_fold_init
from lowering VEC_INIT_EXPR too soon. And handle COMPOUND_EXPR inside
TARGET_EXPR better.
PR c++/104300
PR c++/92385
gcc/cp/ChangeLog:
* cp-tree.h (get_vec_init_expr): New.
(target_expr_needs_replace): New.
* cp-gimplify.cc (cp_gimplify_init_expr): Use it.
(struct cp_fold_data): New.
(cp_fold_r): Only genericize inits at end of fn.
(cp_fold_function): Here.
(cp_fully_fold_init): Not here.
* init.cc (build_vec_init): Use get_vec_init_expr.
* tree.cc (build_vec_init_expr): Likewise.
* typeck2.cc (split_nonconstant_init_1): Likewise.
(process_init_constructor): Wrap VEC_INIT_EXPR in
TARGET_EXPR.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/initlist-array14.C: New test.
Diff:
---
gcc/cp/cp-tree.h | 27 +++++++++++++++++++
gcc/cp/cp-gimplify.cc | 39 ++++++++++++++++++---------
gcc/cp/init.cc | 12 ++++++---
gcc/cp/tree.cc | 4 +--
gcc/cp/typeck2.cc | 9 +++++--
gcc/testsuite/g++.dg/cpp0x/initlist-array14.C | 12 +++++++++
6 files changed, 82 insertions(+), 21 deletions(-)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b9eb71fbc3a..d71be0a5bc7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4201,6 +4201,18 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define VEC_INIT_EXPR_VALUE_INIT(NODE) \
TREE_LANG_FLAG_1 (VEC_INIT_EXPR_CHECK (NODE))
+/* If T is a VEC_INIT_EXPR, return it, possibly stripping a TARGET_EXPR
+ wrapper. Otherwise, return null. */
+inline tree
+get_vec_init_expr (tree t)
+{
+ if (t && TREE_CODE (t) == TARGET_EXPR)
+ t = TARGET_EXPR_INITIAL (t);
+ if (t && TREE_CODE (t) == VEC_INIT_EXPR)
+ return t;
+ return NULL_TREE;
+}
+
/* The condition under which this MUST_NOT_THROW_EXPR actually blocks
exceptions. NULL_TREE means 'true'. */
#define MUST_NOT_THROW_COND(NODE) \
@@ -5361,6 +5373,21 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
&& TARGET_EXPR_INITIAL (NODE) \
&& !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (NODE))))
+/* True if T is a TARGET_EXPR for which we'll need to replace_decl to use it as
+ an initializer. */
+inline bool
+target_expr_needs_replace (tree t)
+{
+ if (!t || TREE_CODE (t) != TARGET_EXPR)
+ return false;
+ tree init = TARGET_EXPR_INITIAL (t);
+ if (!init || !VOID_TYPE_P (TREE_TYPE (init)))
+ return false;
+ while (TREE_CODE (init) == COMPOUND_EXPR)
+ init = TREE_OPERAND (init, 1);
+ return TREE_CODE (init) != AGGR_INIT_EXPR;
+}
+
/* True if EXPR expresses direct-initialization of a TYPE. */
#define DIRECT_INIT_EXPR_P(TYPE,EXPR) \
(TREE_CODE (EXPR) == TARGET_EXPR && TREE_LANG_FLAG_2 (EXPR) \
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index d1c653c5fda..d7323fb5c09 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -249,8 +249,7 @@ cp_gimplify_init_expr (tree *expr_p)
if (TREE_CODE (from) == TARGET_EXPR)
if (tree init = TARGET_EXPR_INITIAL (from))
{
- if (VOID_TYPE_P (TREE_TYPE (init))
- && TREE_CODE (init) != AGGR_INIT_EXPR)
+ if (target_expr_needs_replace (from))
{
/* If this was changed by cp_genericize_target_expr, we need to
walk into it to replace uses of the slot. */
@@ -950,14 +949,23 @@ struct cp_genericize_data
/* Perform any pre-gimplification folding of C++ front end trees to
GENERIC.
- Note: The folding of none-omp cases is something to move into
+ Note: The folding of non-omp cases is something to move into
the middle-end. As for now we have most foldings only on GENERIC
in fold-const, we need to perform this before transformation to
GIMPLE-form. */
-static tree
-cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
+struct cp_fold_data
{
+ hash_set<tree> pset;
+ bool genericize; // called from cp_fold_function?
+
+ cp_fold_data (bool g): genericize (g) {}
+};
+
+static tree
+cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_)
+{
+ cp_fold_data *data = (cp_fold_data*)data_;
tree stmt = *stmt_p;
enum tree_code code = TREE_CODE (stmt);
@@ -967,7 +975,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
if (TREE_CODE (PTRMEM_CST_MEMBER (stmt)) == FUNCTION_DECL
&& DECL_IMMEDIATE_FUNCTION_P (PTRMEM_CST_MEMBER (stmt)))
{
- if (!((hash_set<tree> *) data)->add (stmt))
+ if (!data->pset.add (stmt))
error_at (PTRMEM_CST_LOCATION (stmt),
"taking address of an immediate function %qD",
PTRMEM_CST_MEMBER (stmt));
@@ -1001,7 +1009,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
*stmt_p = stmt = cp_fold (*stmt_p);
- if (((hash_set<tree> *) data)->add (stmt))
+ if (data->pset.add (stmt))
{
/* Don't walk subtrees of stmts we've already walked once, otherwise
we can have exponential complexity with e.g. lots of nested
@@ -1075,12 +1083,17 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
}
break;
+ /* These are only for genericize time; they're here rather than in
+ cp_genericize to avoid problems with the invisible reference
+ transition. */
case INIT_EXPR:
- cp_genericize_init_expr (stmt_p);
+ if (data->genericize)
+ cp_genericize_init_expr (stmt_p);
break;
case TARGET_EXPR:
- cp_genericize_target_expr (stmt_p);
+ if (data->genericize)
+ cp_genericize_target_expr (stmt_p);
break;
default:
@@ -1096,8 +1109,8 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
void
cp_fold_function (tree fndecl)
{
- hash_set<tree> pset;
- cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &pset, NULL);
+ cp_fold_data data (/*genericize*/true);
+ cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &data, NULL);
}
/* Turn SPACESHIP_EXPR EXPR into GENERIC. */
@@ -2358,8 +2371,8 @@ cp_fully_fold_init (tree x)
if (processing_template_decl)
return x;
x = cp_fully_fold (x);
- hash_set<tree> pset;
- cp_walk_tree (&x, cp_fold_r, &pset, NULL);
+ cp_fold_data data (/*genericize*/false);
+ cp_walk_tree (&x, cp_fold_r, &data, NULL);
return x;
}
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 1f047831b6d..fcb255f1ac7 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -4368,8 +4368,8 @@ build_vec_init (tree base, tree maxindex, tree init,
&& from_array != 2)
init = TARGET_EXPR_INITIAL (init);
- if (init && TREE_CODE (init) == VEC_INIT_EXPR)
- init = VEC_INIT_EXPR_INIT (init);
+ if (tree vi = get_vec_init_expr (init))
+ init = VEC_INIT_EXPR_INIT (vi);
bool direct_init = false;
if (from_array && init && BRACE_ENCLOSED_INITIALIZER_P (init)
@@ -4581,10 +4581,14 @@ build_vec_init (tree base, tree maxindex, tree init,
num_initialized_elts++;
+ /* We need to see sub-array TARGET_EXPR before cp_fold_r so we can
+ handle cleanup flags properly. */
+ gcc_checking_assert (!target_expr_needs_replace (elt));
+
if (digested)
one_init = build2 (INIT_EXPR, type, baseref, elt);
- else if (TREE_CODE (elt) == VEC_INIT_EXPR)
- one_init = expand_vec_init_expr (baseref, elt, complain, flags);
+ else if (tree vi = get_vec_init_expr (elt))
+ one_init = expand_vec_init_expr (baseref, vi, complain, flags);
else if (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
one_init = build_aggr_init (baseref, elt, 0, complain);
else
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 2d8f2c551c0..6e9be713c51 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -785,8 +785,8 @@ build_vec_init_elt (tree type, tree init, tsubst_flags_t complain)
tree
build_vec_init_expr (tree type, tree init, tsubst_flags_t complain)
{
- if (init && TREE_CODE (init) == VEC_INIT_EXPR)
- return init;
+ if (tree vi = get_vec_init_expr (init))
+ return vi;
tree elt_init;
if (init && TREE_CODE (init) == CONSTRUCTOR
diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
index f439dd54866..4015bd53257 100644
--- a/gcc/cp/typeck2.cc
+++ b/gcc/cp/typeck2.cc
@@ -548,6 +548,10 @@ split_nonconstant_init_1 (tree dest, tree init, bool last,
bool elt_last = last && idx == CONSTRUCTOR_NELTS (init) - 1;
+ /* We need to see sub-array TARGET_EXPR before cp_fold_r so we can
+ handle cleanup flags properly. */
+ gcc_checking_assert (!target_expr_needs_replace (value));
+
if (TREE_CODE (value) == CONSTRUCTOR)
{
if (!split_nonconstant_init_1 (sub, value, elt_last, flags)
@@ -574,9 +578,9 @@ split_nonconstant_init_1 (tree dest, tree init, bool last,
num_split_elts++;
}
}
- else if (TREE_CODE (value) == VEC_INIT_EXPR)
+ else if (tree vi = get_vec_init_expr (value))
{
- add_stmt (expand_vec_init_expr (sub, value, tf_warning_or_error,
+ add_stmt (expand_vec_init_expr (sub, vi, tf_warning_or_error,
flags));
/* Mark element for removal. */
@@ -1925,6 +1929,7 @@ process_init_constructor (tree type, tree init, int nested, int flags,
initializer-clause until later so we can use a loop. */
TREE_TYPE (init) = init_list_type_node;
init = build_vec_init_expr (type, init, complain);
+ init = get_target_expr (init);
}
return init;
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array14.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array14.C
new file mode 100644
index 00000000000..baa4afc91fd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array14.C
@@ -0,0 +1,12 @@
+// PR c++/104300
+// { dg-do compile { target c++11 } }
+
+struct ss {
+ char r;
+ ss();
+};
+struct a {
+ ss e[6];
+};
+a vv;
+void ff() { vv = {}; }
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-02-05 5:57 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-05 5:57 [gcc r12-7069] c++: assignment, aggregate, array [PR104300] Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).