diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bdbdd36389b2..3dc569c0596b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2004-01-10 Giovanni Bajo + + DR 337 + PR c++/9256 + * pt.c (tsubst): Substitution must fail if we are attempting to + create an array with element type that is an abstract class type. + * decl.c (cp_finish_decl): Strip pointers and array types recursively + before calling abstract_virtuals_error. + 2004-01-09 Alexandre Oliva * name-lookup.c (qualified_lookup_using_namespace): Consider diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c7a294d9b2f7..3ce6d0a4b6c0 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4879,8 +4879,19 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) || TREE_CODE (type) == METHOD_TYPE) abstract_virtuals_error (decl, strip_array_types (TREE_TYPE (type))); + else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE) + { + /* If it's either a pointer or an array type, strip through all + of them but the last one. If the last is an array type, issue + an error if the element type is abstract. */ + while (POINTER_TYPE_P (TREE_TYPE (type)) + || TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE) + type = TREE_TYPE (type); + if (TREE_CODE (type) == ARRAY_TYPE) + abstract_virtuals_error (decl, TREE_TYPE (type)); + } else - abstract_virtuals_error (decl, strip_array_types (type)); + abstract_virtuals_error (decl, type); if (TREE_CODE (decl) == FUNCTION_DECL || TREE_TYPE (decl) == error_mark_node) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6b099a1d3ab2..040476c2181d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6975,7 +6975,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) The deduction may fail for any of the following reasons: -- Attempting to create an array with an element type that - is void, a function type, or a reference type. */ + is void, a function type, or a reference type, or [DR337] + an abstract class type. */ if (TREE_CODE (type) == VOID_TYPE || TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == REFERENCE_TYPE) @@ -6984,6 +6985,13 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) error ("creating array of `%T'", type); return error_mark_node; } + if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type)) + { + if (complain & tf_error) + error ("creating array of `%T', which is an abstract class type", + type); + return error_mark_node; + } r = build_cplus_array_type (type, domain); return r;