aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-11-25 17:05:24 -0500
committerJason Merrill <jason@redhat.com>2020-12-04 17:47:05 -0500
commita95753214b55d21e5b44eeb098cccf88d44c94dd (patch)
treebaf54176edc281d78bf9eb314bb06b74aa59a089 /gcc/testsuite
parentdf933e307b1950ce12472660dcac1765b8eb431d (diff)
downloadgcc-a95753214b55d21e5b44eeb098cccf88d44c94dd.zip
gcc-a95753214b55d21e5b44eeb098cccf88d44c94dd.tar.gz
gcc-a95753214b55d21e5b44eeb098cccf88d44c94dd.tar.bz2
c++: Fix deduction from auto template parameter [PR93083]
The check in do_class_deduction to handle passing one class placeholder template parm as an argument for itself needed to be extended to also handle equivalent parms from other templates. gcc/cp/ChangeLog: PR c++/93083 * pt.c (convert_template_argument): Handle equivalent placeholders. (do_class_deduction): Look through EXPR_PACK_EXPANSION, too. gcc/testsuite/ChangeLog: PR c++/93083 * g++.dg/cpp2a/nontype-class40.C: New test.
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/nontype-class40.C79
1 files changed, 79 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class40.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class40.C
new file mode 100644
index 0000000..d193544
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class40.C
@@ -0,0 +1,79 @@
+// PR c++/93083
+// { dg-do compile { target c++20 } }
+
+template<unsigned N>
+struct FixedString
+{
+ char buf[N + 1]{};
+ constexpr FixedString(char const* s) {
+ for (unsigned i = 0; i != N; ++i) buf[i] = s[i];
+ }
+
+ auto operator<=>(const FixedString&) const = default;
+ constexpr operator char const*() const { return buf; }
+ constexpr static unsigned size() noexcept { return N; }
+};
+
+template<unsigned N> FixedString(char const (&)[N]) -> FixedString<N - 1>;
+
+template <FixedString... names>
+struct name_list
+{
+ template <FixedString name>
+ using add_name = name_list<
+ names...,
+ FixedString<name.size()>{ name }
+ >;
+};
+
+
+int main()
+{
+ using names =
+ name_list<>
+ ::add_name<"Zaphod Beeblebrox">;
+
+}
+
+// ----------------
+
+template <int N> struct literal {
+ constexpr literal(const char (&input)[N]) noexcept { }
+ constexpr literal(const literal &) noexcept { }
+};
+
+template <literal Name, int id> struct field { };
+
+template <literal Name> struct field<Name, 1u> { };
+
+// ----------------
+
+template <int N>
+struct use_as_nttp {};
+
+template <use_as_nttp Value>
+struct has_nttp {};
+
+template <use_as_nttp Value>
+using has_nttp_2 = has_nttp<Value>;
+
+// ----------------
+
+using size_t = decltype(sizeof(0));
+
+template <size_t N>
+struct string_literal
+{
+ constexpr string_literal(const char*) {}
+ string_literal(string_literal const&) = default;
+};
+template <size_t N>
+string_literal(const char (&)[N]) -> string_literal<N - 1>;
+
+template <string_literal Str>
+struct type_string { };
+
+template <string_literal Str>
+void foo() {
+ type_string<Str>{};
+}