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
This commit is contained in:
parent
ac6dbb1a40
commit
77095a6ab1
@ -1,3 +1,9 @@
|
||||
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>
|
||||
|
||||
PR tree-optimization/79340
|
||||
|
@ -1,5 +1,10 @@
|
||||
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
|
||||
* constexpr.c (maybe_constant_value): Fold maybe_constant_value_1
|
||||
back in. Don't cache constants.
|
||||
|
@ -4818,7 +4818,7 @@ build_clone (tree fn, tree name)
|
||||
|
||||
/* A base constructor inheriting from a virtual base doesn't get the
|
||||
arguments. */
|
||||
if (ctor_omit_inherited_parms (fn))
|
||||
if (ctor_omit_inherited_parms (clone))
|
||||
DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))) = NULL_TREE;
|
||||
|
||||
for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms))
|
||||
|
@ -621,9 +621,21 @@ maybe_clone_body (tree fn)
|
||||
function. */
|
||||
else
|
||||
{
|
||||
decl_map->put (parm, clone_parm);
|
||||
tree replacement;
|
||||
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
|
||||
// { dg-final { scan-assembler "_ZN1YCI21WEi" } }
|
||||
// { 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.
|
||||
// { dg-final { scan-assembler "_ZN1VCI21WEi" } }
|
||||
// { dg-final { scan-tree-dump "V::V .this, _1.;" "gimple" } }
|
||||
|
14
gcc/testsuite/g++.dg/init/ctor12.C
Normal file
14
gcc/testsuite/g++.dg/init/ctor12.C
Normal file
@ -0,0 +1,14 @@
|
||||
// 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)
|
||||
copy_body_data *id = (copy_body_data *) data;
|
||||
tree fn = id->src_fn;
|
||||
tree new_block;
|
||||
bool copied = false;
|
||||
|
||||
/* Begin by recognizing trees that we'll completely rewrite for the
|
||||
inlining context. Our output for these trees is completely
|
||||
@ -1242,40 +1241,10 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
|
||||
*walk_subtrees = 0;
|
||||
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
|
||||
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.
|
||||
When inlining we want EXPRs without block appear in the block
|
||||
|
Loading…
Reference in New Issue
Block a user