c++: Check abstract type only on object creation. [PR86252]
authorJason Merrill <jason@redhat.com>
Fri, 13 Nov 2020 21:33:50 +0000 (16:33 -0500)
committerJason Merrill <jason@redhat.com>
Sun, 15 Nov 2020 17:07:13 +0000 (12:07 -0500)
commitbaf38d2e363971ed8baa5f82b2eaf21cd8e74aae
treef5888a935e669ab96ba8aef052e2f514213f9d80
parent82b6d25d289195d41e53fc91f63325864e3e28d0
c++: Check abstract type only on object creation. [PR86252]

Abstract checking has been problematic for a while; when I implemented an
earlier issue resolution to do more checking it led to undesirable
instantiations, and so backed some of it out.  During the C++20 process we
decided with P0929R2 that we should go the other way, and only check
abstractness when we're actually creating an object, not when merely forming
an array or function type.  This means that we can remove the machinery for
checking whether a newly complete class makes some earlier declaration
ill-formed.  This change was moved as a DR, so I'm applying it to all
standard levels.  This could be reconsidered if it causes problems, but I
don't expect it to.

The change to the libstdc++ result_of test brings the expected behavior in
line with that for incomplete types, but as in PR97841 I think the libstdc++
handling of incomplete types in this and other type_traits is itself wrong,
so I expect these lines and others to change again before long.

gcc/cp/ChangeLog:

* decl.c (cp_finish_decl): Only check abstractness on definition.
(require_complete_types_for_parms): Check abstractness here.
(create_array_type_for_decl): Not here.
(grokdeclarator, grokparms, complete_vars): Not here.
* pt.c (tsubst, tsubst_arg_types, tsubst_function_type): Not here.
* typeck2.c (struct pending_abstract_type): Remove.
(struct abstract_type_hasher): Remove.
(abstract_pending_vars, complete_type_check_abstract): Remove.
(abstract_virtuals_error_sfinae): Handle arrays.
* call.c (conv_is_prvalue): Split out from...
(conv_binds_ref_to_prvalue): ...here.
(implicit_conversion_1): Rename from implicit_conversion.
(implicit_conversion): An abstract prvalue is bad.
(convert_like_internal): Don't complain if expr is already
error_mark_node.

gcc/testsuite/ChangeLog:

* g++.dg/other/abstract1.C: Adjust.
* g++.dg/other/abstract2.C: Adjust.
* g++.dg/other/abstract4.C: Adjust.
* g++.dg/other/abstract5.C: Adjust.
* g++.dg/other/abstract8.C: New test.
* g++.dg/template/sfinae-dr657.C: Adjust.
* g++.old-deja/g++.other/decl3.C: Adjust.

libstdc++-v3/ChangeLog:

* testsuite/20_util/result_of/sfinae_friendly_1.cc: Adjust.
12 files changed:
gcc/cp/call.c
gcc/cp/decl.c
gcc/cp/pt.c
gcc/cp/typeck2.c
gcc/testsuite/g++.dg/other/abstract1.C
gcc/testsuite/g++.dg/other/abstract2.C
gcc/testsuite/g++.dg/other/abstract4.C
gcc/testsuite/g++.dg/other/abstract5.C
gcc/testsuite/g++.dg/other/abstract8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/sfinae-dr657.C
gcc/testsuite/g++.old-deja/g++.other/decl3.C
libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_1.cc