PR c++/78771 - ICE with inherited constructor.
authorJason Merrill <jason@redhat.com>
Fri, 27 Jan 2017 16:48:34 +0000 (11:48 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 27 Jan 2017 16:48:34 +0000 (11:48 -0500)
* 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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/method.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/pr78771-new.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/pr78771-old.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/pr78771.C [new file with mode: 0644]

index 406d382135f38570fe770c7143e81f236c1d4d4e..1f31731bc6919f7bdf3cb59b4ace17ed32311c68 100644 (file)
@@ -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
index a78e1a9c8a2eb4c2fca25e5c7e08b0a78bee6c9b..8030d7ebb0be45d71905f1a73004cd08ef809448 100644 (file)
@@ -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;
index b7c26a1829f53d9ce05eb1cbcbef0c753b2ec68d..03a973084e5cff53e213a4c3ee9c220f8ae35226 100644 (file)
@@ -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;
                        }
index 5b366f0e9609b65f91aef8666bcf459e39b6d693..e80b80606b56e6ad1c449b8c2bd2536715d3016f 100644 (file)
@@ -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);
index 57334b4c44e112bb20977af4da2a147a3095606f..0ba95d636cd68121f9fc6e6ac03807217728a4e1 100644 (file)
@@ -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 (file)
index 0000000..f489f86
--- /dev/null
@@ -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 (file)
index 0000000..b723b11
--- /dev/null
@@ -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 (file)
index 0000000..9178494
--- /dev/null
@@ -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) {}