aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/typeck2.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-11-13 16:33:50 -0500
committerJason Merrill <jason@redhat.com>2020-11-15 12:07:13 -0500
commitbaf38d2e363971ed8baa5f82b2eaf21cd8e74aae (patch)
treef5888a935e669ab96ba8aef052e2f514213f9d80 /gcc/cp/typeck2.c
parent82b6d25d289195d41e53fc91f63325864e3e28d0 (diff)
downloadgcc-baf38d2e363971ed8baa5f82b2eaf21cd8e74aae.zip
gcc-baf38d2e363971ed8baa5f82b2eaf21cd8e74aae.tar.gz
gcc-baf38d2e363971ed8baa5f82b2eaf21cd8e74aae.tar.bz2
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.
Diffstat (limited to 'gcc/cp/typeck2.c')
-rw-r--r--gcc/cp/typeck2.c159
1 files changed, 7 insertions, 152 deletions
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 445e2a2..4128699 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -123,123 +123,6 @@ cxx_readonly_error (location_t loc, tree arg, enum lvalue_use errstring)
readonly_error (loc, arg, errstring);
}
-/* Structure that holds information about declarations whose type was
- incomplete and we could not check whether it was abstract or not. */
-
-struct GTY((chain_next ("%h.next"), for_user)) pending_abstract_type {
- /* Declaration which we are checking for abstractness. It is either
- a DECL node, or an IDENTIFIER_NODE if we do not have a full
- declaration available. */
- tree decl;
-
- /* Type which will be checked for abstractness. */
- tree type;
-
- /* Kind of use in an unnamed declarator. */
- enum abstract_class_use use;
-
- /* Position of the declaration. This is only needed for IDENTIFIER_NODEs,
- because DECLs already carry locus information. */
- location_t locus;
-
- /* Link to the next element in list. */
- struct pending_abstract_type* next;
-};
-
-struct abstract_type_hasher : ggc_ptr_hash<pending_abstract_type>
-{
- typedef tree compare_type;
- static hashval_t hash (pending_abstract_type *);
- static bool equal (pending_abstract_type *, tree);
-};
-
-/* Compute the hash value of the node VAL. This function is used by the
- hash table abstract_pending_vars. */
-
-hashval_t
-abstract_type_hasher::hash (pending_abstract_type *pat)
-{
- return (hashval_t) TYPE_UID (pat->type);
-}
-
-
-/* Compare node VAL1 with the type VAL2. This function is used by the
- hash table abstract_pending_vars. */
-
-bool
-abstract_type_hasher::equal (pending_abstract_type *pat1, tree type2)
-{
- return (pat1->type == type2);
-}
-
-/* Hash table that maintains pending_abstract_type nodes, for which we still
- need to check for type abstractness. The key of the table is the type
- of the declaration. */
-static GTY (()) hash_table<abstract_type_hasher> *abstract_pending_vars = NULL;
-
-static int abstract_virtuals_error_sfinae (tree, tree, abstract_class_use, tsubst_flags_t);
-
-/* This function is called after TYPE is completed, and will check if there
- are pending declarations for which we still need to verify the abstractness
- of TYPE, and emit a diagnostic (through abstract_virtuals_error) if TYPE
- turned out to be incomplete. */
-
-void
-complete_type_check_abstract (tree type)
-{
- struct pending_abstract_type *pat;
- location_t cur_loc = input_location;
-
- gcc_assert (COMPLETE_TYPE_P (type));
-
- if (!abstract_pending_vars)
- return;
-
- /* Retrieve the list of pending declarations for this type. */
- pending_abstract_type **slot
- = abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
- NO_INSERT);
- if (!slot)
- return;
- pat = *slot;
- gcc_assert (pat);
-
- /* If the type is not abstract, do not do anything. */
- if (CLASSTYPE_PURE_VIRTUALS (type))
- {
- struct pending_abstract_type *prev = 0, *next;
-
- /* Reverse the list to emit the errors in top-down order. */
- for (; pat; pat = next)
- {
- next = pat->next;
- pat->next = prev;
- prev = pat;
- }
- pat = prev;
-
- /* Go through the list, and call abstract_virtuals_error for each
- element: it will issue a diagnostic if the type is abstract. */
- while (pat)
- {
- gcc_assert (type == pat->type);
-
- /* Tweak input_location so that the diagnostic appears at the correct
- location. Notice that this is only needed if the decl is an
- IDENTIFIER_NODE. */
- input_location = pat->locus;
- abstract_virtuals_error_sfinae (pat->decl, pat->type, pat->use,
- tf_warning_or_error);
- pat = pat->next;
- }
- }
-
- abstract_pending_vars->clear_slot (slot);
-
- input_location = cur_loc;
-}
-
-
/* If TYPE has abstract virtual functions, issue an error about trying
to create an object of that type. DECL is the object declared, or
NULL_TREE if the declaration is unavailable, in which case USE specifies
@@ -252,6 +135,13 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
{
vec<tree, va_gc> *pure;
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ decl = NULL_TREE;
+ use = ACU_ARRAY;
+ type = strip_array_types (type);
+ }
+
/* This function applies only to classes. Any other entity can never
be abstract. */
if (!CLASS_TYPE_P (type))
@@ -266,38 +156,6 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
complete_type (type);
#endif
- /* 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
- name. */
- if (!COMPLETE_TYPE_P (type) && (complain & tf_error))
- {
- struct pending_abstract_type *pat;
-
- gcc_assert (!decl || DECL_P (decl) || identifier_p (decl));
-
- if (!abstract_pending_vars)
- abstract_pending_vars
- = hash_table<abstract_type_hasher>::create_ggc (31);
-
- pending_abstract_type **slot
- = abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
- INSERT);
-
- pat = ggc_alloc<pending_abstract_type> ();
- pat->type = type;
- pat->decl = decl;
- pat->use = use;
- pat->locus = ((decl && DECL_P (decl))
- ? DECL_SOURCE_LOCATION (decl)
- : input_location);
-
- pat->next = *slot;
- *slot = pat;
-
- return 0;
- }
-
if (!TYPE_SIZE (type))
/* TYPE is being defined, and during that time
CLASSTYPE_PURE_VIRTUALS holds the inline friends. */
@@ -2594,6 +2452,3 @@ require_complete_eh_spec_types (tree fntype, tree decl)
}
}
}
-
-
-#include "gt-cp-typeck2.h"