From 95ffad49d5499e3de6fcd0d261fa3870755995c2 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 16 Mar 2013 22:36:40 -0400 Subject: [PATCH] DR 337 PR c++/17232 DR 337 PR c++/17232 * pt.c (tsubst) [ARRAY_TYPE]: Use abstract_virtuals_error_sfinae. * typeck2.c (abstract_virtuals_error_sfinae): Call complete_type. From-SVN: r196734 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/pt.c | 10 +++------- gcc/cp/typeck2.c | 4 ++++ gcc/testsuite/g++.dg/template/abstract-dr337.C | 13 +++++++++++++ 4 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/abstract-dr337.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2f5f87313a8..20414dcb7f2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2013-03-16 Jason Merrill + DR 337 + PR c++/17232 + * pt.c (tsubst) [ARRAY_TYPE]: Use abstract_virtuals_error_sfinae. + * typeck2.c (abstract_virtuals_error_sfinae): Call complete_type. + DR 657 * pt.c (tsubst_function_type): Call abstract_virtuals_error_sfinae. (tsubst_arg_types): Likewise. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index cad1c60a118..ce07fa495df 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11653,13 +11653,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) error ("creating array of %qT", type); return error_mark_node; } - if (ABSTRACT_CLASS_TYPE_P (type)) - { - if (complain & tf_error) - error ("creating array of %qT, which is an abstract class type", - type); - return error_mark_node; - } + + if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain)) + return error_mark_node; r = build_cplus_array_type (type, domain); diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index d227a821d43..dc17776c0a3 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -258,6 +258,10 @@ abstract_virtuals_error_sfinae (tree decl, tree type, tsubst_flags_t complain) return 0; type = TYPE_MAIN_VARIANT (type); + /* In SFINAE context, force instantiation. */ + if (!(complain & tf_error)) + complete_type (type); + /* If the type is incomplete, we register it within a hash table, so that we can check again once it is completed. This makes sense only for objects for which we have a declaration or at least a diff --git a/gcc/testsuite/g++.dg/template/abstract-dr337.C b/gcc/testsuite/g++.dg/template/abstract-dr337.C new file mode 100644 index 00000000000..de84f907ff1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/abstract-dr337.C @@ -0,0 +1,13 @@ +// PR c++/17232 (DR 337) + +template +class A { + virtual void f() = 0; +}; + +template +void g(T (*a)[1]) {} // { dg-error "abstract" } + +int main() { + g >(0); // { dg-error "no matching function" } +} -- 2.30.2