From: Nedim Šehić <nedimsehi...@gmail.com> Regtested on x86_64-pc-linux-gnu.
This patch fixes deduction for member array types from parenthesized initializers which use braces and string literals. PR c++/121518 gcc/cp/ChangeLog: * pt.cc (maybe_aggr_guide): Add deduction for brace and string literal initializer cases. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/class-deduction-aggr17.C: New test. Co-Authored-By: Nathaniel Shead <nathanielosh...@gmail.com> Signed-off-by: Nedim Šehić <nedimsehi...@gmail.com> --- gcc/cp/pt.cc | 22 +++-- .../g++.dg/cpp2a/class-deduction-aggr17.C | 88 +++++++++++++++++++ 2 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr17.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index b6b13edd03f..35c3ce517e8 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -31116,22 +31116,34 @@ maybe_aggr_guide (tree tmpl, tree init, vec<tree,va_gc> *args) } else if (TREE_CODE (init) == TREE_LIST) { - int len = list_length (init); + tree elt = init; for (tree binfo : BINFO_BASE_BINFOS (TYPE_BINFO (template_type))) { - if (!len) + if (!elt) break; parms = tree_cons (NULL_TREE, BINFO_TYPE (binfo), parms); - --len; + elt = TREE_CHAIN (elt); } for (tree field = TYPE_FIELDS (template_type); - len; - --len, field = DECL_CHAIN (field)) + elt; + elt = TREE_CHAIN (elt), field = DECL_CHAIN (field)) { field = next_aggregate_field (field); if (!field) return NULL_TREE; tree ftype = finish_decltype_type (field, true, complain); + tree arg = tree_strip_any_location_wrapper (TREE_VALUE (elt)); + if (TREE_CODE (ftype) == ARRAY_TYPE) + { + if (BRACE_ENCLOSED_INITIALIZER_P (arg)) + ftype = cp_build_reference_type (ftype, true); + else if (TREE_CODE (arg) == STRING_CST) + { + ftype = cp_build_qualified_type + (ftype, cp_type_quals (ftype) | TYPE_QUAL_CONST); + ftype = cp_build_reference_type (ftype, false); + } + } parms = tree_cons (NULL_TREE, ftype, parms); } } diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr17.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr17.C new file mode 100644 index 00000000000..9fa63369426 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr17.C @@ -0,0 +1,88 @@ +// PR c++/121518 +// { dg-do compile { target c++20 } } + +#include <cstddef> +#include <utility> + +template <std::size_t N> +struct Str { + char x[N]{}; +}; + +struct MovableType { + MovableType() = default; + MovableType(MovableType const&) = delete; + MovableType(MovableType&&) = default; +}; + +struct ImmovableType { + ImmovableType() = default; + ImmovableType(ImmovableType&&) = delete; +}; + +template <typename T, std::size_t N> +struct Deduct { + T x[N]{}; +}; + +template<class, class> struct same; +template<class T> struct same<T, T> {}; + +Str s0("a"); +same<decltype(s0), Str<2>> c0; +Str s1{"a"}; +same<decltype(s1), Str<2>> c1; +Str s2 = {"a"}; +same<decltype(s2), Str<2>> c2; + +Str s3({'a', '\0'}); +same<decltype(s3), Str<2>> c3; +Str s4{{'a', '\0'}}; +same<decltype(s4), Str<2>> c4; +Str s5 = {{'a', '\0'}}; +same<decltype(s5), Str<2>> c5; + +Deduct ds0("a"); +same<decltype(ds0), Deduct<char, 2>> c15; +Deduct ds1{"a"}; +same<decltype(ds1), Deduct<char, 2>> c16; +Deduct ds2 = {"a"}; +same<decltype(ds2), Deduct<char, 2>> c17; + +Deduct ds3({'a', '\0'}); +same<decltype(ds3), Deduct<char, 2>> c18; +Deduct ds4{{'a', '\0'}}; +same<decltype(ds4), Deduct<char, 2>> c19; +Deduct ds5 = {{'a', '\0'}}; +same<decltype(ds5), Deduct<char, 2>> c20; + +MovableType mt; +Deduct dm0({MovableType{}}); +same<decltype(dm0), Deduct<MovableType, 1>> c21; +Deduct dm1({MovableType{}, std::move(mt)}); +same<decltype(dm1), Deduct<MovableType, 2>> c22; + +Deduct dm2{{MovableType{}}}; +same<decltype(dm2), Deduct<MovableType, 1>> c23; +Deduct dm3{{MovableType{}, std::move(mt)}}; +same<decltype(dm3), Deduct<MovableType, 2>> c24; + +Deduct dm4 = {{MovableType{}}}; +same<decltype(dm4), Deduct<MovableType, 1>> c25; +Deduct dm5 = {{MovableType{}, std::move(mt)}}; +same<decltype(dm5), Deduct<MovableType, 2>> c26; + +Deduct dm6({MovableType{}, mt}); // { dg-error "use of deleted function" } + +ImmovableType it; +Deduct di0({ImmovableType{}}); +same<decltype(di0), Deduct<ImmovableType, 1>> c27; +Deduct di1({ImmovableType{}, std::move(it)}); // { dg-error "use of deleted function" } + +Deduct di2{{ImmovableType{}}}; +same<decltype(di2), Deduct<ImmovableType, 1>> c28; +Deduct di3{{ImmovableType{}, std::move(it)}}; // { dg-error "use of deleted function" } + +Deduct di4 = {{ImmovableType{}}}; +same<decltype(di4), Deduct<ImmovableType, 1>> c29; +Deduct di5 = {{ImmovableType{}, std::move(it)}}; // { dg-error "use of deleted function" } -- 2.50.1