diff options
author | Marek Polacek <polacek@redhat.com> | 2022-01-26 17:29:19 -0500 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2022-01-27 08:18:43 -0500 |
commit | 0c0f453c4af4880c522c8472c33eef42bee9eda1 (patch) | |
tree | c42601c3b1f5514fd17a1409d7238c6731a23ecb /gcc/cp | |
parent | 76ef38e3178a11e76a66b4d4c0e10e85fe186a45 (diff) | |
download | gcc-0c0f453c4af4880c522c8472c33eef42bee9eda1.zip gcc-0c0f453c4af4880c522c8472c33eef42bee9eda1.tar.gz gcc-0c0f453c4af4880c522c8472c33eef42bee9eda1.tar.bz2 |
c++: new-expr of array of deduced class tmpl [PR101988]
In r12-1933 I attempted to implement DR2397 aka allowing
int a[3];
auto (&r)[3] = a;
by removing the type_uses_auto check in create_array_type_for_decl.
That may have gone too far, because it also allows arrays of
CLASS_PLACEHOLDER_TEMPLATE and it looks like [dcl.type.class.deduct]
prohibits that: "...the declared type of the variable shall be cv T,
where T is the placeholder." However, in /2 it explicitly states that
"A placeholder for a deduced class type can also be used in the
type-specifier-seq in the new-type-id or type-id of a new-expression."
In this PR, it manifested by making us accept invalid
template<class T> struct A { A(T); };
auto p = new A[]{1};
[expr.new]/2 says that such a construct is treated as an invented
declaration of the form
A x[]{1};
but, I think, that ought to be ill-formed as per above. So this patch
sort of restores the create_array_type_for_decl check. I should mention
that the difference between [] and [1] is due to cp_parser_new_type_id:
if (*nelts == NULL_TREE)
/* Leave [] in the declarator. */;
and groktypename returning different types based on that.
PR c++/101988
gcc/cp/ChangeLog:
* decl.cc (create_array_type_for_decl): Reject forming an array of
placeholder for a deduced class type.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/class-deduction-new1.C: New test.
* g++.dg/cpp23/auto-array2.C: New test.
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/decl.cc | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 6534a7f..10e6956 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -11087,6 +11087,18 @@ create_array_type_for_decl (tree name, tree type, tree size, location_t loc) if (type == error_mark_node || size == error_mark_node) return error_mark_node; + /* [dcl.type.class.deduct] prohibits forming an array of placeholder + for a deduced class type. */ + if (is_auto (type) && CLASS_PLACEHOLDER_TEMPLATE (type)) + { + if (name) + error_at (loc, "%qD declared as array of template placeholder " + "type %qT", name, type); + else + error ("creating array of template placeholder type %qT", type); + return error_mark_node; + } + /* If there are some types which cannot be array elements, issue an error-message and return. */ switch (TREE_CODE (type)) |