aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/class.c3
-rw-r--r--gcc/cp/pt.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/explicit11.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/explicit12.C17
5 files changed, 45 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4917719..812c8c1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 3ad1b89..20689e4 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5d4f5ef..b0f0664 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
index 0000000..06d607f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/explicit11.C
@@ -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
index 0000000..5c14c01
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/explicit12.C
@@ -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;
+}