+2019-08-05 Tom Honermann <tom@honermann.net>
+
+ * parser.c (cp_parser_template_declaration_after_parameters): Enable
+ class template argument deduction for non-type template parameters
+ in literal operator templates.
+
2019-08-05 Marek Polacek <polacek@redhat.com>
PR c++/91338 - Implement P1161R3: Deprecate a[b,c].
{
tree parm_list = TREE_VEC_ELT (parameter_list, 0);
tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
- if (CLASS_TYPE_P (TREE_TYPE (parm)))
+ if (TREE_CODE (parm) != PARM_DECL)
+ ok = false;
+ else if (MAYBE_CLASS_TYPE_P (TREE_TYPE (parm))
+ && !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
/* OK, C++20 string literal operator template. We don't need
to warn in lower dialects here because we will have already
warned about the template parameter. */;
tree type = INNERMOST_TEMPLATE_PARMS (parm_type);
tree parm_list = TREE_VEC_ELT (parameter_list, 1);
tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
- if (parm == error_mark_node
+ if (TREE_CODE (parm) != PARM_DECL
|| TREE_TYPE (parm) != TREE_TYPE (type)
|| !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
ok = false;
+2019-08-02 Tom Honermann <tom@honermann.net>
+
+ PR c++/88095
+ * g++.dg/cpp2a/udlit-class-nttp-ctad.C: New test.
+ * g++.dg/cpp2a/udlit-class-nttp-ctad-neg.C: New test.
+ * g++.dg/cpp2a/udlit-class-nttp-ctad-neg2.C: New test.
+ * g++.dg/cpp2a/udlit-class-nttp.C: New test.
+ * g++.dg/cpp2a/udlit-class-nttp-neg.C: New test.
+ * g++.dg/cpp2a/udlit-class-nttp-neg2.C: New test.
+
2019-08-05 Steven g. Kargl <kargl@gcc.gnu.org>
PR fortran/91372
--- /dev/null
+// PR c++/88095
+// Test class non-type template parameters for literal operator templates.
+// Validate handling of failed class template argument deduction.
+// { dg-do compile { target c++2a } }
+
+namespace std {
+using size_t = decltype(sizeof(int));
+}
+
+template <typename CharT, std::size_t N>
+struct fixed_string {
+ constexpr static std::size_t length = N;
+ constexpr fixed_string(...) { }
+ // auto operator<=> (const fixed_string&) = default;
+};
+// Missing deduction guide.
+
+template <fixed_string fs>
+constexpr std::size_t operator"" _udl() {
+ return decltype(fs)::length;
+}
+
+static_assert("test"_udl == 5); // { dg-error "15:no matching function for call to" }
+ // { dg-error "15:class template argument deduction failed" "" { target *-*-* } .-1 }
--- /dev/null
+// PR c++/88095
+// Test class non-type template parameters for literal operator templates.
+// Validate rejection of class template parameter packs.
+// { dg-do compile { target c++2a } }
+
+namespace std {
+using size_t = decltype(sizeof(int));
+}
+
+template <typename CharT, std::size_t N>
+struct fixed_string {
+ constexpr static std::size_t length = N;
+ constexpr fixed_string(...) { }
+ // auto operator<=> (const fixed_string&) = default;
+};
+template <typename CharT, std::size_t N>
+fixed_string(const CharT (&str)[N]) -> fixed_string<CharT, N>;
+
+template <fixed_string...>
+int operator"" _udl(); // { dg-error "5:literal operator template .int operator\"\"_udl\\(\\). has invalid parameter list" }
--- /dev/null
+// PR c++/88095
+// Test class non-type template parameters for literal operator templates.
+// Validate support for class template argument deduction.
+// { dg-do compile { target c++2a } }
+
+namespace std {
+using size_t = decltype(sizeof(int));
+}
+
+template <typename CharT, std::size_t N>
+struct fixed_string {
+ constexpr static std::size_t length = N;
+ constexpr fixed_string(...) { }
+ // auto operator<=> (const fixed_string&) = default;
+};
+template <typename CharT, std::size_t N>
+fixed_string(const CharT (&str)[N]) -> fixed_string<CharT, N>;
+
+template <fixed_string fs>
+constexpr std::size_t operator"" _udl() {
+ return decltype(fs)::length;
+}
+
+static_assert("test"_udl == 5);
--- /dev/null
+// PR c++/88095
+// Test class non-type template parameters for literal operator templates.
+// Validate that parameter packs are rejected.
+// { dg-do compile { target c++2a } }
+
+struct literal_class {
+ constexpr literal_class(...) { }
+ // auto operator<=> (const fixed_string&) = default;
+};
+
+template <literal_class...>
+int operator"" _udl(); // { dg-error "5:literal operator template .int operator\"\"_udl\\(\\). has invalid parameter list" }
--- /dev/null
+// PR c++/88095
+// Test class non-type template parameters for literal operator templates.
+// Validate that non-literal class types are rejected.
+// { dg-do compile { target c++2a } }
+
+struct non_literal_class {
+ constexpr non_literal_class(...) { }
+ ~non_literal_class() {}
+ // auto operator<=> (const non_literal_fixed_string&) = default;
+};
+
+template <non_literal_class> // { dg-error "11:is not a valid type for a template non-type parameter because it is not literal" }
+int operator"" _udl(); // { dg-error "5:literal operator template .int operator\"\"_udl\\(\\). has invalid parameter list" }
--- /dev/null
+// PR c++/88095
+// Test class non-type template parameters for literal operator templates.
+// Validate basic support.
+// { dg-do compile { target c++2a } }
+
+struct literal_class {
+ constexpr literal_class(...) { }
+ // auto operator<=> (const fixed_string&) = default;
+};
+
+template <literal_class>
+constexpr int operator"" _udl() {
+ return 1;
+}
+
+static_assert("test"_udl == 1);