PR c++/57728 - explicit instantiation and defaulted functions
authorJason Merrill <jason@redhat.com>
Fri, 26 Aug 2016 15:10:51 +0000 (11:10 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 26 Aug 2016 15:10:51 +0000 (11:10 -0400)
* pt.c (do_type_instantiation): Don't mess with non-user-provided
member functions.

From-SVN: r239782

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/explicit11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/explicit12.C [new file with mode: 0644]

index 491771969854ff62c556dfa6dfd1557ed210e8d7..812c8c10f66618b908e05059e712ba7b51b88c41 100644 (file)
@@ -1,3 +1,9 @@
+2016-08-15  Jason Merrill  <jason@redhat.com>
+
+       PR c++/57728
+       * pt.c (do_type_instantiation): Don't mess with non-user-provided
+       member functions.
+
 2016-08-25  Marek Polacek  <polacek@redhat.com>
 
        * parser.c (cp_parser_binary_expression): Pass LHS to
index 3ad1b8910fcc67c7defa77549ba7db11f97c4c2e..20689e4dd063aabd1cee9aeebc94b539457f882e 100644 (file)
@@ -5186,8 +5186,7 @@ in_class_defaulted_default_constructor (tree t)
 }
 
 /* Returns true iff FN is a user-provided function, i.e. user-declared
-   and not defaulted at its first declaration; or explicit, private,
-   protected, or non-const.  */
+   and not defaulted at its first declaration.  */
 
 bool
 user_provided_p (tree fn)
index 5d4f5efc79d5af272722d0376cbec1da5a484b84..b0f06649c582f9654143efb7f660c92fad74c0b4 100644 (file)
@@ -21479,7 +21479,8 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
     if (! static_p)
       for (tmp = TYPE_METHODS (t); tmp; tmp = DECL_CHAIN (tmp))
        if (TREE_CODE (tmp) == FUNCTION_DECL
-           && DECL_TEMPLATE_INSTANTIATION (tmp))
+           && DECL_TEMPLATE_INSTANTIATION (tmp)
+           && user_provided_p (tmp))
          instantiate_class_member (tmp, extern_p);
 
     for (tmp = TYPE_FIELDS (t); tmp; tmp = DECL_CHAIN (tmp))
diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit11.C b/gcc/testsuite/g++.dg/cpp0x/explicit11.C
new file mode 100644 (file)
index 0000000..06d607f
--- /dev/null
@@ -0,0 +1,19 @@
+// Test that we treat defaulted-in-class members like implicitly declared
+// members for explicit instantiation.
+
+// { dg-do compile { target c++11 } }
+
+template<typename T>
+struct A
+{
+  T x;
+  A() = default;
+  A(const A &other) = default;
+  A& operator=(const A&) = default;
+};
+
+template class A<int>;
+
+// { dg-final { scan-assembler-not "_ZN1AIiEC1Ev" } }
+// { dg-final { scan-assembler-not "_ZN1AIiEC1ERKS0_" } }
+// { dg-final { scan-assembler-not "_ZN1AIiEaSERKS0_" } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit12.C b/gcc/testsuite/g++.dg/cpp0x/explicit12.C
new file mode 100644 (file)
index 0000000..5c14c01
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/57728
+// { dg-do link { target c++11 } }
+
+template<typename T>
+struct A
+{
+  T x;
+  A() = default;
+  A(const A &other) = delete;
+};
+
+extern template class A<int>;
+
+int main()
+{
+  A<int> a;
+}