Commit 77095a6a by Jason Merrill Committed by Jason Merrill

PR c++/78689 - ICE on constructor with label

gcc/
	* tree-inline.c (copy_tree_body_r) [COND_EXPR]: Revert change to
	avoid copying non-taken branch.
gcc/cp/
	* optimize.c (maybe_clone_body): Replace omitted parameters with
	null lvalues.
	* class.c (build_clone): Fix logic for omitting inherited parms.

From-SVN: r245172
parent ac6dbb1a
2017-02-03 Jason Merrill <jason@redhat.com>
PR c++/78689
* tree-inline.c (copy_tree_body_r) [COND_EXPR]: Revert change to
avoid copying non-taken branch.
2017-02-03 Jakub Jelinek <jakub@redhat.com> 2017-02-03 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/79340 PR tree-optimization/79340
......
2017-02-03 Jason Merrill <jason@redhat.com> 2017-02-03 Jason Merrill <jason@redhat.com>
PR c++/78689 - ICE on constructor with label
* optimize.c (maybe_clone_body): Replace omitted parameters with
null lvalues.
* class.c (build_clone): Fix logic for omitting inherited parms.
PR c++/12245 - excessive memory use PR c++/12245 - excessive memory use
* constexpr.c (maybe_constant_value): Fold maybe_constant_value_1 * constexpr.c (maybe_constant_value): Fold maybe_constant_value_1
back in. Don't cache constants. back in. Don't cache constants.
......
...@@ -4818,7 +4818,7 @@ build_clone (tree fn, tree name) ...@@ -4818,7 +4818,7 @@ build_clone (tree fn, tree name)
/* A base constructor inheriting from a virtual base doesn't get the /* A base constructor inheriting from a virtual base doesn't get the
arguments. */ arguments. */
if (ctor_omit_inherited_parms (fn)) if (ctor_omit_inherited_parms (clone))
DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))) = NULL_TREE; DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))) = NULL_TREE;
for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms)) for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms))
......
...@@ -621,9 +621,21 @@ maybe_clone_body (tree fn) ...@@ -621,9 +621,21 @@ maybe_clone_body (tree fn)
function. */ function. */
else else
{ {
decl_map->put (parm, clone_parm); tree replacement;
if (clone_parm) if (clone_parm)
clone_parm = DECL_CHAIN (clone_parm); {
replacement = clone_parm;
clone_parm = DECL_CHAIN (clone_parm);
}
else
{
/* Inheriting ctors can omit parameters from the base
clone. Replace them with null lvalues. */
tree reftype = build_reference_type (TREE_TYPE (parm));
replacement = fold_convert (reftype, null_pointer_node);
replacement = convert_from_reference (replacement);
}
decl_map->put (parm, replacement);
} }
} }
......
...@@ -14,6 +14,9 @@ Z z(0); // OK: initialization of Y does not invoke default constructor of X ...@@ -14,6 +14,9 @@ Z z(0); // OK: initialization of Y does not invoke default constructor of X
// { dg-final { scan-assembler "_ZN1YCI21WEi" } } // { dg-final { scan-assembler "_ZN1YCI21WEi" } }
// { dg-final { scan-tree-dump "Y::Y ._2, _3.;" "gimple" } } // { dg-final { scan-tree-dump "Y::Y ._2, _3.;" "gimple" } }
// And that we aren't expecting the int, either.
// { dg-final { scan-tree-dump-not "Y::Y.int\[^\n\]*int" "gimple" } }
// And that we *are* passing the int along to V::V. // And that we *are* passing the int along to V::V.
// { dg-final { scan-assembler "_ZN1VCI21WEi" } } // { dg-final { scan-assembler "_ZN1VCI21WEi" } }
// { dg-final { scan-tree-dump "V::V .this, _1.;" "gimple" } } // { dg-final { scan-tree-dump "V::V .this, _1.;" "gimple" } }
// PR c++/78689 - ICE on constructor with label
struct e {
e() {
goto aj;
if (0)
aj:;
}
};
void f()
{
struct e x;
}
...@@ -1045,7 +1045,6 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data) ...@@ -1045,7 +1045,6 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
copy_body_data *id = (copy_body_data *) data; copy_body_data *id = (copy_body_data *) data;
tree fn = id->src_fn; tree fn = id->src_fn;
tree new_block; tree new_block;
bool copied = false;
/* Begin by recognizing trees that we'll completely rewrite for the /* Begin by recognizing trees that we'll completely rewrite for the
inlining context. Our output for these trees is completely inlining context. Our output for these trees is completely
...@@ -1242,40 +1241,10 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data) ...@@ -1242,40 +1241,10 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
*walk_subtrees = 0; *walk_subtrees = 0;
return NULL; return NULL;
} }
else if (TREE_CODE (*tp) == COND_EXPR)
{
tree cond = TREE_OPERAND (*tp, 0);
walk_tree (&cond, copy_tree_body_r, data, NULL);
tree folded = fold (cond);
if (TREE_CODE (folded) == INTEGER_CST)
{
/* Only copy the taken branch; for a C++ base constructor clone
inherited from a virtual base, copying the other branch leads
to references to parameters that were optimized away. */
tree branch = (integer_nonzerop (folded)
? TREE_OPERAND (*tp, 1)
: TREE_OPERAND (*tp, 2));
tree type = TREE_TYPE (*tp);
if (VOID_TYPE_P (type)
|| type == TREE_TYPE (branch))
{
*tp = branch;
return copy_tree_body_r (tp, walk_subtrees, data);
}
}
/* Avoid copying the condition twice. */
copy_tree_r (tp, walk_subtrees, NULL);
TREE_OPERAND (*tp, 0) = cond;
walk_tree (&TREE_OPERAND (*tp, 1), copy_tree_body_r, data, NULL);
walk_tree (&TREE_OPERAND (*tp, 2), copy_tree_body_r, data, NULL);
*walk_subtrees = 0;
copied = true;
}
/* Here is the "usual case". Copy this tree node, and then /* Here is the "usual case". Copy this tree node, and then
tweak some special cases. */ tweak some special cases. */
if (!copied) copy_tree_r (tp, walk_subtrees, NULL);
copy_tree_r (tp, walk_subtrees, NULL);
/* If EXPR has block defined, map it to newly constructed block. /* If EXPR has block defined, map it to newly constructed block.
When inlining we want EXPRs without block appear in the block When inlining we want EXPRs without block appear in the block
......
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