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
This commit is contained in:
Jason Merrill 2016-08-26 11:10:51 -04:00 committed by Jason Merrill
parent 10491e4c04
commit 9729a5d524
5 changed files with 45 additions and 3 deletions

View 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

View 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)

View 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))

View File

@ -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_" } }

View File

@ -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;
}