Commit 817a77e4 by Jason Merrill Committed by Jason Merrill

PR c++/77659 - ICE with new and C++14 aggregate NSDMI

	* init.c (build_new): Make backups of any CONSTRUCTORs in init.
	(build_new_1): Use replace_placeholders.
	* tree.c (replace_placeholders_t): Also track whether we've seen a
	placeholder.
	(replace_placeholders, replace_placeholders_r): Adjust.
	* cp-tree.h: Adjust.

From-SVN: r245372
parent 95bbcf58
2017-02-11 Jason Merrill <jason@redhat.com>
PR c++/77659 - ICE with new and C++14 aggregate NSDMI
* init.c (build_new): Make backups of any CONSTRUCTORs in init.
(build_new_1): Use replace_placeholders.
* tree.c (replace_placeholders_t): Also track whether we've seen a
placeholder.
(replace_placeholders, replace_placeholders_r): Adjust.
* cp-tree.h: Adjust.
PR c++/77790 - ICE with auto function in C++11 mode
* decl.c (undeduced_auto_decl): Remove C++14 limitation.
(require_deduced_type): Add complain parm, return bool.
......
......@@ -6658,7 +6658,7 @@ extern tree array_type_nelts_total (tree);
extern tree array_type_nelts_top (tree);
extern tree break_out_target_exprs (tree);
extern tree build_ctor_subob_ref (tree, tree, tree);
extern tree replace_placeholders (tree, tree);
extern tree replace_placeholders (tree, tree, bool * = NULL);
extern tree get_type_decl (tree);
extern tree decl_namespace_context (tree);
extern bool decl_anon_ns_mem_p (const_tree);
......
......@@ -3282,7 +3282,19 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
init_expr = cp_build_modify_expr (input_location, init_expr,
INIT_EXPR, ie, complain);
}
stable = stabilize_init (init_expr, &init_preeval_expr);
/* If the initializer uses C++14 aggregate NSDMI that refer to the
object being initialized, replace them now and don't try to
preevaluate. */
bool had_placeholder = false;
if (cxx_dialect >= cxx14
&& !processing_template_decl
&& TREE_CODE (init_expr) == INIT_EXPR)
TREE_OPERAND (init_expr, 1)
= replace_placeholders (TREE_OPERAND (init_expr, 1),
TREE_OPERAND (init_expr, 0),
&had_placeholder);
stable = (!had_placeholder
&& stabilize_init (init_expr, &init_preeval_expr));
}
if (init_expr == error_mark_node)
......@@ -3454,7 +3466,17 @@ build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
orig_placement = make_tree_vector_copy (*placement);
orig_nelts = nelts;
if (*init)
orig_init = make_tree_vector_copy (*init);
{
orig_init = make_tree_vector_copy (*init);
/* Also copy any CONSTRUCTORs in *init, since reshape_init and
digest_init clobber them in place. */
for (unsigned i = 0; i < orig_init->length(); ++i)
{
tree e = (**init)[i];
if (TREE_CODE (e) == CONSTRUCTOR)
(**init)[i] = copy_node (e);
}
}
make_args_non_dependent (*placement);
if (nelts)
......
......@@ -2728,13 +2728,20 @@ build_ctor_subob_ref (tree index, tree type, tree obj)
return obj;
}
struct replace_placeholders_t
{
tree obj; /* The object to be substituted for a PLACEHOLDER_EXPR. */
bool seen; /* Whether we've encountered a PLACEHOLDER_EXPR. */
};
/* Like substitute_placeholder_in_expr, but handle C++ tree codes and
build up subexpressions as we go deeper. */
static tree
replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
{
tree obj = static_cast<tree>(data_);
replace_placeholders_t *d = static_cast<replace_placeholders_t*>(data_);
tree obj = d->obj;
if (TREE_CONSTANT (*t))
{
......@@ -2753,6 +2760,7 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
gcc_assert (TREE_CODE (x) == COMPONENT_REF);
*t = x;
*walk_subtrees = false;
d->seen = true;
}
break;
......@@ -2778,9 +2786,10 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
if (TREE_CODE (*valp) == TARGET_EXPR)
valp = &TARGET_EXPR_INITIAL (*valp);
}
d->obj = subob;
cp_walk_tree (valp, replace_placeholders_r,
subob, NULL);
data_, NULL);
d->obj = obj;
}
*walk_subtrees = false;
break;
......@@ -2794,12 +2803,15 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
}
tree
replace_placeholders (tree exp, tree obj)
replace_placeholders (tree exp, tree obj, bool *seen_p)
{
tree *tp = &exp;
replace_placeholders_t data = { obj, false };
if (TREE_CODE (exp) == TARGET_EXPR)
tp = &TARGET_EXPR_INITIAL (exp);
cp_walk_tree (tp, replace_placeholders_r, obj, NULL);
cp_walk_tree (tp, replace_placeholders_r, &data, NULL);
if (seen_p)
*seen_p = data.seen;
return exp;
}
......
// PR c++/77659
// { dg-do compile { target c++14 } }
template <typename Type> Type get_max_value(Type);
struct A {
struct B {
int baz = get_max_value(baz);
};
template <typename> void m_fn1() { new B{}; }
};
void foo() {
A a;
a.m_fn1<int>();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment