aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-02-03 17:42:37 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-02-03 17:42:37 -0500
commit77095a6ab13996a38b0a360d8ef9fc6cc6bc5234 (patch)
tree3d5b23c76bf199ee7e8f14bc642997ba0d96ab88 /gcc
parentac6dbb1a4042eaa719afbb9c7a02e4f409b8aa75 (diff)
downloadgcc-77095a6ab13996a38b0a360d8ef9fc6cc6bc5234.zip
gcc-77095a6ab13996a38b0a360d8ef9fc6cc6bc5234.tar.gz
gcc-77095a6ab13996a38b0a360d8ef9fc6cc6bc5234.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/optimize.c16
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/inh-ctor23.C3
-rw-r--r--gcc/testsuite/g++.dg/init/ctor12.C14
-rw-r--r--gcc/tree-inline.c33
7 files changed, 44 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5bfbff5..044f720 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f77e6cb..d032028 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index d99ebcd..7ec07c9 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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))
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index f61d035..933612c 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -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);
}
}
diff --git a/gcc/testsuite/g++.dg/cpp1z/inh-ctor23.C b/gcc/testsuite/g++.dg/cpp1z/inh-ctor23.C
index 0c862f7..c0cf040 100644
--- a/gcc/testsuite/g++.dg/cpp1z/inh-ctor23.C
+++ b/gcc/testsuite/g++.dg/cpp1z/inh-ctor23.C
@@ -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" } }
diff --git a/gcc/testsuite/g++.dg/init/ctor12.C b/gcc/testsuite/g++.dg/init/ctor12.C
new file mode 100644
index 0000000..7c1aab7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/ctor12.C
@@ -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;
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index d63c70f..138b992 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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