From 9729a5d5241257d07aa2a9c2fa6c3abbd73e25e5 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 26 Aug 2016 11:10:51 -0400 Subject: [PATCH] PR c++/57728 - explicit instantiation and defaulted functions * pt.c (do_type_instantiation): Don't mess with non-user-provided member functions. From-SVN: r239782 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/class.c | 3 +-- gcc/cp/pt.c | 3 ++- gcc/testsuite/g++.dg/cpp0x/explicit11.C | 19 +++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/explicit12.C | 17 +++++++++++++++++ 5 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/explicit11.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/explicit12.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 49177196985..812c8c10f66 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-08-15 Jason Merrill + + PR c++/57728 + * pt.c (do_type_instantiation): Don't mess with non-user-provided + member functions. + 2016-08-25 Marek Polacek * parser.c (cp_parser_binary_expression): Pass LHS to diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 3ad1b8910fc..20689e4dd06 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 5d4f5efc79d..b0f06649c58 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 00000000000..06d607f1a98 --- /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 +struct A +{ + T x; + A() = default; + A(const A &other) = default; + A& operator=(const A&) = default; +}; + +template class A; + +// { 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 00000000000..5c14c019d88 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/explicit12.C @@ -0,0 +1,17 @@ +// PR c++/57728 +// { dg-do link { target c++11 } } + +template +struct A +{ + T x; + A() = default; + A(const A &other) = delete; +}; + +extern template class A; + +int main() +{ + A a; +} -- 2.30.2