aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-01-27 11:48:34 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-01-27 11:48:34 -0500
commit20f058d0986d8e7f81c1e45217b6d4c361dc089b (patch)
tree95c5d020797f1cfdd1538426d670c45790934a50
parenta7d47f352663d16c12cb3a40459b546d166023d7 (diff)
downloadgcc-20f058d0986d8e7f81c1e45217b6d4c361dc089b.zip
gcc-20f058d0986d8e7f81c1e45217b6d4c361dc089b.tar.gz
gcc-20f058d0986d8e7f81c1e45217b6d4c361dc089b.tar.bz2
PR c++/78771 - ICE with inherited constructor.
* call.c (build_over_call): Call deduce_inheriting_ctor here. * pt.c (tsubst_decl): Not here. * class.c (add_method): Or here. * method.c (deduce_inheriting_ctor): Handle clones. (implicitly_declare_fn): Don't deduce inheriting ctors yet. From-SVN: r244988
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/call.c6
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/method.c14
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr78771-new.C28
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr78771-old.C28
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/pr78771.C27
8 files changed, 109 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 406d382..1f31731 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2017-01-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/78771 - ICE with inherited constructor.
+ * call.c (build_over_call): Call deduce_inheriting_ctor here.
+ * pt.c (tsubst_decl): Not here.
+ * class.c (add_method): Or here.
+ * method.c (deduce_inheriting_ctor): Handle clones.
+ (implicitly_declare_fn): Don't deduce inheriting ctors yet.
+
2017-01-27 Adam Butcher <adam@jessamine.co.uk>
PR c++/64382
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index a78e1a9..8030d7e 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7581,6 +7581,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
joust (cand, w->loser, 1, complain);
}
+ /* OK, we're actually calling this inherited constructor; set its deletedness
+ appropriately. We can get away with doing this here because calling is
+ the only way to refer to a constructor. */
+ if (DECL_INHERITED_CTOR (fn))
+ deduce_inheriting_ctor (fn);
+
/* Make =delete work with SFINAE. */
if (DECL_DELETED_FN (fn) && !(complain & tf_error))
return error_mark_node;
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index b7c26a1..03a9730 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1197,8 +1197,6 @@ add_method (tree type, tree method, tree using_decl)
SET_DECL_INHERITED_CTOR
(fn, ovl_cons (DECL_INHERITED_CTOR (method),
DECL_INHERITED_CTOR (fn)));
- /* Adjust deletedness and such. */
- deduce_inheriting_ctor (fn);
/* And discard the new one. */
return false;
}
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 5b366f0..e80b806 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1855,6 +1855,7 @@ explain_implicit_non_constexpr (tree decl)
void
deduce_inheriting_ctor (tree decl)
{
+ decl = DECL_ORIGIN (decl);
gcc_assert (DECL_INHERITED_CTOR (decl));
tree spec;
bool trivial, constexpr_, deleted;
@@ -1868,6 +1869,13 @@ deduce_inheriting_ctor (tree decl)
deleted = true;
DECL_DELETED_FN (decl) = deleted;
TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec);
+
+ tree clone;
+ FOR_EACH_CLONE (clone, decl)
+ {
+ DECL_DELETED_FN (clone) = deleted;
+ TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec);
+ }
}
/* Implicitly declare the special function indicated by KIND, as a
@@ -1968,10 +1976,10 @@ implicitly_declare_fn (special_function_kind kind, tree type,
bool trivial_p = false;
- if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
+ if (inherited_ctor)
{
- /* For an inheriting constructor template, just copy these flags from
- the inherited constructor template for now. */
+ /* For an inheriting constructor, just copy these flags from the
+ inherited constructor until deduce_inheriting_ctor. */
raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor));
deleted_p = DECL_DELETED_FN (inherited_ctor);
constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 57334b4..0ba95d6 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -12358,8 +12358,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
maybe_retrofit_in_chrg (r);
if (DECL_CONSTRUCTOR_P (r))
grok_ctor_properties (ctx, r);
- if (DECL_INHERITED_CTOR (r))
- deduce_inheriting_ctor (r);
/* If this is an instantiation of a member template, clone it.
If it isn't, that'll be handled by
clone_constructors_and_destructors. */
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr78771-new.C b/gcc/testsuite/g++.dg/cpp0x/pr78771-new.C
new file mode 100644
index 0000000..f489f86
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr78771-new.C
@@ -0,0 +1,28 @@
+// PR c++/78771
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fnew-inheriting-ctors" }
+
+// ICE instantiating a deleted inherited ctor
+
+struct Base
+{
+ template <typename U> Base (U);
+
+ Base (int);
+};
+
+struct Derived;
+
+struct Middle : Base
+{
+ using Base::Base;
+
+ Middle (Derived);
+};
+
+struct Derived : Middle
+{
+ using Middle::Middle;
+};
+
+Middle::Middle (Derived) : Middle (0) {}
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr78771-old.C b/gcc/testsuite/g++.dg/cpp0x/pr78771-old.C
new file mode 100644
index 0000000..b723b11
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr78771-old.C
@@ -0,0 +1,28 @@
+// PR c++/78771
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fno-new-inheriting-ctors" }
+
+// ICE instantiating a deleted inherited ctor
+
+struct Base
+{
+ template <typename U> Base (U);
+
+ Base (int);
+};
+
+struct Derived;
+
+struct Middle : Base
+{
+ using Base::Base;
+
+ Middle (Derived);
+};
+
+struct Derived : Middle
+{
+ using Middle::Middle;
+};
+
+Middle::Middle (Derived) : Middle (0) {}
diff --git a/gcc/testsuite/g++.dg/cpp1z/pr78771.C b/gcc/testsuite/g++.dg/cpp1z/pr78771.C
new file mode 100644
index 0000000..9178494
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/pr78771.C
@@ -0,0 +1,27 @@
+// PR c++/78771
+// { dg-options -std=c++1z }
+
+// ICE instantiating a deleted inherited ctor
+
+struct Base
+{
+ template <typename U> Base (U);
+
+ Base (int);
+};
+
+struct Derived;
+
+struct Middle : Base
+{
+ using Base::Base;
+
+ Middle (Derived);
+};
+
+struct Derived : Middle
+{
+ using Middle::Middle;
+};
+
+Middle::Middle (Derived) : Middle (0) {}