diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a75001963996229..7063fea41efda15 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -99,6 +99,20 @@ C++ Specific Potentially Breaking Changes // Was error, now evaluates to false. constexpr bool b = f() == g(); +- The warning ``-Wdeprecated-literal-operator`` is now on by default, as this is + something that WG21 has shown interest in removing from the language. The + result is that anyone who is compiling with ``-Werror`` should see this + diagnostic. To fix this diagnostic, simply removing the space character from + between the ``operator""`` and the user defined literal name will make the + source no longer deprecated. This is consistent with `CWG2521 _`. + + .. code-block:: c++ + + // Now diagnoses by default. + unsigned operator"" _udl_name(unsigned long long); + // Fixed version: + unsigned operator""_udl_name(unsigned long long); + ABI Changes in This Version --------------------------- @@ -215,6 +229,10 @@ Resolutions to C++ Defect Reports - Clang now allows trailing requires clause on explicit deduction guides. (`CWG2707: Deduction guides cannot have a trailing requires-clause `_). +- Clang now diagnoses a space in the first production of a ``literal-operator-id`` + by default. + (`CWG2521: User-defined literals and reserved identifiers `_). + C Language Changes ------------------ @@ -378,6 +396,10 @@ Improvements to Clang's diagnostics - The warning for an unsupported type for a named register variable is now phrased ``unsupported type for named register variable``, instead of ``bad type for named register variable``. This makes it clear that the type is not supported at all, rather than being suboptimal in some way the error fails to mention (#GH111550). + +- Clang now emits a ``-Wdepredcated-literal-operator`` diagnostic, even if the + name was a reserved name, which we improperly allowed to suppress the + diagnostic. Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 9ae26e48fd322a4..e880771ef18f4c4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -439,7 +439,7 @@ def warn_reserved_extern_symbol: Warning< InGroup, DefaultIgnore; def warn_deprecated_literal_operator_id: Warning< "identifier %0 preceded by whitespace in a literal operator declaration " - "is deprecated">, InGroup, DefaultIgnore; + "is deprecated">, InGroup; def warn_reserved_module_name : Warning< "%0 is a reserved name for a module">, InGroup; def warn_import_implementation_partition_unit_in_interface_unit : Warning< diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp index c9c9d927a5902ef..16151c94464f999 100644 --- a/clang/lib/Basic/IdentifierTable.cpp +++ b/clang/lib/Basic/IdentifierTable.cpp @@ -406,6 +406,9 @@ ReservedLiteralSuffixIdStatus IdentifierInfo::isReservedLiteralSuffixId() const { StringRef Name = getName(); + // Note: the diag::warn_deprecated_literal_operator_id diagnostic depends on + // this being the first check we do, so if this order changes, we have to fix + // that as well. if (Name[0] != '_') return ReservedLiteralSuffixIdStatus::NotStartsWithUnderscore; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 8e9bcb10a80b46f..d39a545b66c151e 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -503,17 +503,23 @@ bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS, const IdentifierInfo *II = Name.Identifier; ReservedIdentifierStatus Status = II->isReserved(PP.getLangOpts()); SourceLocation Loc = Name.getEndLoc(); - if (!PP.getSourceManager().isInSystemHeader(Loc)) { - if (auto Hint = FixItHint::CreateReplacement( - Name.getSourceRange(), - (StringRef("operator\"\"") + II->getName()).str()); - isReservedInAllContexts(Status)) { - Diag(Loc, diag::warn_reserved_extern_symbol) - << II << static_cast(Status) << Hint; - } else { - Diag(Loc, diag::warn_deprecated_literal_operator_id) << II << Hint; - } - } + + auto Hint = FixItHint::CreateReplacement( + Name.getSourceRange(), + (StringRef("operator\"\"") + II->getName()).str()); + + // Only emit this diagnostic if we start with an underscore, else the + // diagnostic for C++11 requiring a space between the quotes and the + // identifier conflicts with this and gets confusing. The diagnostic stating + // this is a reserved name should force the underscore, which gets this + // back. + if (II->isReservedLiteralSuffixId() != + ReservedLiteralSuffixIdStatus::NotStartsWithUnderscore) + Diag(Loc, diag::warn_deprecated_literal_operator_id) << II << Hint; + + if (isReservedInAllContexts(Status)) + Diag(Loc, diag::warn_reserved_extern_symbol) + << II << static_cast(Status) << Hint; } if (!SS.isValid()) diff --git a/clang/test/CXX/drs/cwg14xx.cpp b/clang/test/CXX/drs/cwg14xx.cpp index 5301185d0469829..cb2f34bf5e427fc 100644 --- a/clang/test/CXX/drs/cwg14xx.cpp +++ b/clang/test/CXX/drs/cwg14xx.cpp @@ -627,7 +627,7 @@ int i = N::f(); namespace cwg1479 { // cwg1479: 3.1 #if __cplusplus >= 201103L - int operator"" _a(const char*, std::size_t = 0); + int operator""_a(const char*, std::size_t = 0); // since-cxx11-error@-1 {{literal operator cannot have a default argument}} #endif } diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp index 1924008f15ba580..87a728088ee6e4f 100644 --- a/clang/test/CXX/drs/cwg25xx.cpp +++ b/clang/test/CXX/drs/cwg25xx.cpp @@ -88,6 +88,9 @@ operator"" _div(); using ::cwg2521::operator"" _\u03C0___; using ::cwg2521::operator""_div; // since-cxx11-warning@-2 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}} + +long double operator"" _RESERVED(long double); +// since-cxx11-warning@-1 {{identifier '_RESERVED' preceded by whitespace in a literal operator declaration is deprecated}} #pragma clang diagnostic pop #endif } // namespace cwg2521 diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp index 1c227a1b10d385a..ec478fbba60a18e 100644 --- a/clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wno-deprecated-literal-operator -verify %s void operator "" p31(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}} void operator "" _p31(long double); diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp index 1b5d3880cb61299..6a9d713ca72d2e3 100644 --- a/clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -verify %s +// RUN: %clang_cc1 -std=c++11 -Wno-deprecated-literal-operator -verify %s using size_t = decltype(sizeof(int)); void operator "" wibble(const char *); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}} diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p11.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p11.cpp index 8b5fcf4b609b653..d69a58a7dfad206 100644 --- a/clang/test/CXX/lex/lex.literal/lex.ext/p11.cpp +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p11.cpp @@ -6,16 +6,16 @@ template struct same_type; template struct same_type {}; template using X = T; template...> -int operator "" _x(); // expected-warning {{string literal operator templates are a GNU extension}} +int operator ""_x(); // expected-warning {{string literal operator templates are a GNU extension}} template -double operator "" _x(); +double operator ""_x(); auto a="string"_x; auto b=42_x; same_type test_a; same_type test_b; -char operator "" _x(const char *begin, size_t size); +char operator ""_x(const char *begin, size_t size); auto c="string"_x; auto d=L"string"_x; same_type test_c; diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp index d764989312c246a..e5ab09c628bcfab 100644 --- a/clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp @@ -1,18 +1,18 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s -int &operator "" _x1 (unsigned long long); +int &operator ""_x1 (unsigned long long); int &i1 = 0x123_x1; -double &operator "" _x1 (const char *); +double &operator ""_x1 (const char *); int &i2 = 45_x1; -template char &operator "" _x1 (); +template char &operator ""_x1 (); int &i3 = 0377_x1; int &i4 = 90000000000000000000000000000000000000000000000_x1; // expected-error {{integer literal is too large to be represented in any integer type}} -double &operator "" _x2 (const char *); +double &operator ""_x2 (const char *); double &i5 = 123123123123123123123123123123123123123123123_x2; -template constexpr int operator "" _x3() { return sizeof...(Cs); } +template constexpr int operator ""_x3() { return sizeof...(Cs); } static_assert(123456789012345678901234567890123456789012345678901234567890_x3 == 60, ""); diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp index 011e832c69d7298..7dbe70ce084e761 100644 --- a/clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp @@ -1,18 +1,18 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s -int &operator "" _x1 (long double); +int &operator ""_x1 (long double); int &i1 = 0.123_x1; -double &operator "" _x1 (const char *); +double &operator ""_x1 (const char *); int &i2 = 45._x1; -template char &operator "" _x1 (); +template char &operator ""_x1 (); int &i3 = 0377e-1_x1; int &i4 = 1e1000000_x1; // expected-warning {{too large for type 'long double'}} -double &operator "" _x2 (const char *); +double &operator ""_x2 (const char *); double &i5 = 1e1000000_x2; -template constexpr int operator "" _x3() { return sizeof...(Cs); } +template constexpr int operator ""_x3() { return sizeof...(Cs); } static_assert(1e1000000_x3 == 9, ""); diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp index aee20545ececfce..afadba282e626c9 100644 --- a/clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp @@ -3,19 +3,19 @@ using size_t = decltype(sizeof(int)); -int &operator "" _x1 (const char *); -double &operator "" _x1 (const char *, size_t); +int &operator ""_x1 (const char *); +double &operator ""_x1 (const char *, size_t); double &i1 = "foo"_x1; #if __cplusplus >= 202002L using char8 = float; -float &operator "" _x1 (const char8_t *, size_t); +float &operator ""_x1 (const char8_t *, size_t); #else using char8 = double; #endif char8 &i2 = u8"foo"_x1; double &i3 = L"foo"_x1; // expected-error {{no matching literal operator for call to 'operator""_x1' with arguments of types 'const wchar_t *' and 'unsigned long'}} -char &operator "" _x1(const wchar_t *, size_t); +char &operator ""_x1(const wchar_t *, size_t); char &i4 = L"foo"_x1; // ok double &i5 = R"(foo)"_x1; // ok char8 &i6 = u\ diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp index 23cd7081d5e3ee9..b1df641f2dc43c8 100644 --- a/clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp @@ -2,13 +2,13 @@ using size_t = decltype(sizeof(int)); -int &operator "" _x1 (const char *); +int &operator ""_x1 (const char *); double &i1 = 'a'_x1; // expected-error {{no matching literal operator}} -double &operator "" _x1 (wchar_t); +double &operator ""_x1 (wchar_t); double &i2 = L'a'_x1; double &i3 = 'a'_x1; // expected-error {{no matching literal operator}} -double &i4 = operator"" _x1('a'); // ok +double &i4 = operator""_x1('a'); // ok -char &operator "" _x1(char16_t); +char &operator ""_x1(char16_t); char &i5 = u'a'_x1; // ok double &i6 = L'a'_x1; // ok diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp index 0b40ecdc143fcb0..d571fcb8697eb01 100644 --- a/clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp @@ -10,9 +10,9 @@ template struct same_type {}; namespace std_example { -long double operator "" _w(long double); -std::string operator "" _w(const char16_t*, size_t); -unsigned operator "" _w(const char*); +long double operator ""_w(long double); +std::string operator ""_w(const char16_t*, size_t); +unsigned operator ""_w(const char*); int main() { auto v1 = 1.2_w; // calls operator""_w(1.2L) auto v2 = u"one"_w; // calls operator""_w(u"one", 3) diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp index d9078221ff5e3a8..67d976263e01674 100644 --- a/clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=c++11 -verify %s using size_t = decltype(sizeof(int)); -constexpr const char *operator "" _id(const char *p, size_t) { return p; } +constexpr const char *operator ""_id(const char *p, size_t) { return p; } constexpr const char *s = "foo"_id "bar" "baz"_id "quux"; constexpr bool streq(const char *p, const char *q) { @@ -9,8 +9,8 @@ constexpr bool streq(const char *p, const char *q) { } static_assert(streq(s, "foobarbazquux"), ""); -constexpr const char *operator "" _trim(const char *p, size_t n) { - return *p == ' ' ? operator "" _trim(p + 1, n - 1) : p; +constexpr const char *operator ""_trim(const char *p, size_t n) { + return *p == ' ' ? operator ""_trim(p + 1, n - 1) : p; } constexpr const char *t = " " " "_trim " foo"; static_assert(streq(t, "foo"), ""); diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp index 65e27b41b066804..fbdedd119d3d68e 100644 --- a/clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s using size_t = decltype(sizeof(int)); -void operator "" _x(const wchar_t *, size_t); +void operator ""_x(const wchar_t *, size_t); namespace std_example { diff --git a/clang/test/CXX/over/over.oper/over.literal/p2.cpp b/clang/test/CXX/over/over.oper/over.literal/p2.cpp index f3ebadd2b8b9bc1..cf26806e9e7d757 100644 --- a/clang/test/CXX/over/over.oper/over.literal/p2.cpp +++ b/clang/test/CXX/over/over.oper/over.literal/p2.cpp @@ -1,43 +1,43 @@ // RUN: %clang_cc1 -std=c++11 %s -verify -void operator "" _a(const char *); +void operator ""_a(const char *); namespace N { - using ::operator "" _a; + using ::operator ""_a; - void operator "" _b(const char *); + void operator ""_b(const char *); } -using N::operator "" _b; +using N::operator ""_b; class C { - void operator "" _c(const char *); // expected-error {{must be in a namespace or global scope}} + void operator ""_c(const char *); // expected-error {{must be in a namespace or global scope}} - static void operator "" _c(unsigned long long); // expected-error {{must be in a namespace or global scope}} + static void operator ""_c(unsigned long long); // expected-error {{must be in a namespace or global scope}} - friend void operator "" _d(const char *); + friend void operator ""_d(const char *); }; -int operator "" _e; // expected-error {{cannot be the name of a variable}} +int operator ""_e; // expected-error {{cannot be the name of a variable}} void f() { - int operator "" _f; // expected-error {{cannot be the name of a variable}} + int operator ""_f; // expected-error {{cannot be the name of a variable}} } extern "C++" { - void operator "" _g(const char *); + void operator ""_g(const char *); } -template void operator "" _h() {} +template void operator ""_h() {} -template<> void operator "" _h<'a', 'b', 'c'>() {} +template<> void operator ""_h<'a', 'b', 'c'>() {} -template void operator "" _h<'a', 'b', 'c', 'd'>(); +template void operator ""_h<'a', 'b', 'c', 'd'>(); namespace rdar13605348 { class C { - double operator"" _x(long double value) { return double(value); } // expected-error{{literal operator 'operator""_x' must be in a namespace or global scope}} + double operator""_x(long double value) { return double(value); } // expected-error{{literal operator 'operator""_x' must be in a namespace or global scope}} double value() { return 3.2_x; } // expected-error{{no matching literal operator for call to}} }; diff --git a/clang/test/CXX/over/over.oper/over.literal/p3.cpp b/clang/test/CXX/over/over.oper/over.literal/p3.cpp index 674ace9aee19291..53ebe102630843b 100644 --- a/clang/test/CXX/over/over.oper/over.literal/p3.cpp +++ b/clang/test/CXX/over/over.oper/over.literal/p3.cpp @@ -3,38 +3,38 @@ using size_t = decltype(sizeof(int)); // Acceptable parameter declarations -char operator "" _a(const char *); -char operator "" _a(const char []); -char operator "" _a(unsigned long long); -char operator "" _a(long double); -char operator "" _a(char); -char operator "" _a(const volatile char); -char operator "" _a(wchar_t); -char operator "" _a(char16_t); -char operator "" _a(char32_t); -char operator "" _a(const char *, size_t); -char operator "" _a(const wchar_t *, size_t); -char operator "" _a(const char16_t *, size_t); -char operator "" _a(const char32_t *, size_t); -char operator "" _a(const char [32], size_t); +char operator ""_a(const char *); +char operator ""_a(const char []); +char operator ""_a(unsigned long long); +char operator ""_a(long double); +char operator ""_a(char); +char operator ""_a(const volatile char); +char operator ""_a(wchar_t); +char operator ""_a(char16_t); +char operator ""_a(char32_t); +char operator ""_a(const char *, size_t); +char operator ""_a(const wchar_t *, size_t); +char operator ""_a(const char16_t *, size_t); +char operator ""_a(const char32_t *, size_t); +char operator ""_a(const char [32], size_t); // Unacceptable parameter declarations -char operator "" _b(); // expected-error {{parameter}} -char operator "" _b(const wchar_t *); // expected-error {{parameter}} -char operator "" _b(long long); // expected-error {{parameter}} -char operator "" _b(double); // expected-error {{parameter}} -char operator "" _b(short); // expected-error {{parameter}} -char operator "" _a(char, int = 0); // expected-error {{parameter}} -char operator "" _b(unsigned short); // expected-error {{parameter}} -char operator "" _b(signed char); // expected-error {{parameter}} -char operator "" _b(unsigned char); // expected-error {{parameter}} -char operator "" _b(const short *, size_t); // expected-error {{parameter}} -char operator "" _b(const unsigned short *, size_t); // expected-error {{parameter}} -char operator "" _b(const signed char *, size_t); // expected-error {{parameter}} -char operator "" _b(const unsigned char *, size_t); // expected-error {{parameter}} -char operator "" _a(const volatile char *, size_t); // expected-error {{parameter}} -char operator "" _a(volatile wchar_t *, size_t); // expected-error {{parameter}} -char operator "" _a(char16_t *, size_t); // expected-error {{parameter}} -char operator "" _a(const char32_t *, size_t, bool = false); // expected-error {{parameter}} -char operator "" _a(const char *, signed long); // expected-error {{parameter}} -char operator "" _a(const char *, size_t = 0); // expected-error {{default argument}} +char operator ""_b(); // expected-error {{parameter}} +char operator ""_b(const wchar_t *); // expected-error {{parameter}} +char operator ""_b(long long); // expected-error {{parameter}} +char operator ""_b(double); // expected-error {{parameter}} +char operator ""_b(short); // expected-error {{parameter}} +char operator ""_a(char, int = 0); // expected-error {{parameter}} +char operator ""_b(unsigned short); // expected-error {{parameter}} +char operator ""_b(signed char); // expected-error {{parameter}} +char operator ""_b(unsigned char); // expected-error {{parameter}} +char operator ""_b(const short *, size_t); // expected-error {{parameter}} +char operator ""_b(const unsigned short *, size_t); // expected-error {{parameter}} +char operator ""_b(const signed char *, size_t); // expected-error {{parameter}} +char operator ""_b(const unsigned char *, size_t); // expected-error {{parameter}} +char operator ""_a(const volatile char *, size_t); // expected-error {{parameter}} +char operator ""_a(volatile wchar_t *, size_t); // expected-error {{parameter}} +char operator ""_a(char16_t *, size_t); // expected-error {{parameter}} +char operator ""_a(const char32_t *, size_t, bool = false); // expected-error {{parameter}} +char operator ""_a(const char *, signed long); // expected-error {{parameter}} +char operator ""_a(const char *, size_t = 0); // expected-error {{default argument}} diff --git a/clang/test/CXX/over/over.oper/over.literal/p5.cpp b/clang/test/CXX/over/over.oper/over.literal/p5.cpp index bfad5f00cf6c75c..593aa57b76a81cd 100644 --- a/clang/test/CXX/over/over.oper/over.literal/p5.cpp +++ b/clang/test/CXX/over/over.oper/over.literal/p5.cpp @@ -3,20 +3,20 @@ using size_t = decltype(sizeof(int)); template struct S {}; -template void operator "" _a(); -template S operator "" _a(); +template void operator ""_a(); +template S operator ""_a(); template struct U { - friend int operator "" _a(const char *, size_t); + friend int operator ""_a(const char *, size_t); // FIXME: It's not entirely clear whether this is intended to be legal. - friend U operator "" _a(const T *, size_t); // expected-error {{parameter}} + friend U operator ""_a(const T *, size_t); // expected-error {{parameter}} }; template struct V { - friend void operator "" _b(); // expected-error {{parameters}} + friend void operator ""_b(); // expected-error {{parameters}} }; -template void operator "" _b(); // expected-error {{template}} -template void operator "" _b(int N = 0); // expected-error {{template}} -template void operator "" _b(); // expected-error {{template}} -template T operator "" _b(const char *); // expected-error {{template}} -template int operator "" _b(const T *, size_t); // expected-error {{template}} +template void operator ""_b(); // expected-error {{template}} +template void operator ""_b(int N = 0); // expected-error {{template}} +template void operator ""_b(); // expected-error {{template}} +template T operator ""_b(const char *); // expected-error {{template}} +template int operator ""_b(const T *, size_t); // expected-error {{template}} diff --git a/clang/test/CXX/over/over.oper/over.literal/p6.cpp b/clang/test/CXX/over/over.oper/over.literal/p6.cpp index 9ecf9ccccb14c6b..265050e0a009675 100644 --- a/clang/test/CXX/over/over.oper/over.literal/p6.cpp +++ b/clang/test/CXX/over/over.oper/over.literal/p6.cpp @@ -1,15 +1,15 @@ // RUN: %clang_cc1 -std=c++11 %s -verify // expected-note@+1 {{extern "C" language linkage specification begins here}} -extern "C" void operator "" _a(const char *); // expected-error {{must have C++ linkage}} -extern "C" template void operator "" _b(); // expected-error {{must have C++ linkage}} +extern "C" void operator ""_a(const char *); // expected-error {{must have C++ linkage}} +extern "C" template void operator ""_b(); // expected-error {{must have C++ linkage}} // expected-note@-1 {{extern "C" language linkage specification begins here}} extern "C" { // expected-note 4 {{extern "C" language linkage specification begins here}} - void operator "" _c(const char *); // expected-error {{must have C++ linkage}} - template void operator "" _d(); // expected-error {{must have C++ linkage}} + void operator ""_c(const char *); // expected-error {{must have C++ linkage}} + template void operator ""_d(); // expected-error {{must have C++ linkage}} namespace N { - void operator "" _e(const char *); // expected-error {{must have C++ linkage}} - template void operator "" _f(); // expected-error {{must have C++ linkage}} + void operator ""_e(const char *); // expected-error {{must have C++ linkage}} + template void operator ""_f(); // expected-error {{must have C++ linkage}} } } diff --git a/clang/test/CXX/over/over.oper/over.literal/p7.cpp b/clang/test/CXX/over/over.oper/over.literal/p7.cpp index 74e9457bb55c38c..244f043d4412e73 100644 --- a/clang/test/CXX/over/over.oper/over.literal/p7.cpp +++ b/clang/test/CXX/over/over.oper/over.literal/p7.cpp @@ -1,17 +1,17 @@ // RUN: %clang_cc1 -std=c++11 %s -verify // expected-no-diagnostics -constexpr int operator "" _a(const char *c) { +constexpr int operator ""_a(const char *c) { return c[0]; } -static_assert(operator "" _a("foo") == 'f', ""); +static_assert(operator ""_a("foo") == 'f', ""); void puts(const char *); -static inline void operator "" _puts(const char *c) { +static inline void operator ""_puts(const char *c) { puts(c); } void f() { - operator "" _puts("foo"); - operator "" _puts("bar"); + operator ""_puts("foo"); + operator ""_puts("bar"); } diff --git a/clang/test/CXX/over/over.oper/over.literal/p8.cpp b/clang/test/CXX/over/over.oper/over.literal/p8.cpp index 6644bae7e610d1f..8aa31e1acd6e157 100644 --- a/clang/test/CXX/over/over.oper/over.literal/p8.cpp +++ b/clang/test/CXX/over/over.oper/over.literal/p8.cpp @@ -5,13 +5,13 @@ namespace std { using size_t = decltype(sizeof(int)); } -void operator "" _km(long double); // ok -string operator "" _i18n(const char*, std::size_t); // ok -template int operator "" \u03C0(); // ok, UCN for lowercase pi // expected-warning {{reserved}} +void operator ""_km(long double); // ok +string operator ""_i18n(const char*, std::size_t); // ok +template int operator ""\u03C0(); // ok, UCN for lowercase pi // expected-warning {{reserved}} float operator ""E(const char *); // expected-error {{invalid suffix on literal}} expected-warning {{reserved}} float operator " " B(const char *); // expected-error {{must be '""'}} expected-warning {{reserved}} -string operator "" 5X(const char *, std::size_t); // expected-error {{expected identifier}} -double operator "" _miles(double); // expected-error {{parameter}} +string operator ""5X(const char *, std::size_t); // expected-error {{expected identifier}} +double operator ""_miles(double); // expected-error {{parameter}} template int operator "" j(const char*); // expected-error {{template}} float operator ""_E(const char *); diff --git a/clang/test/FixIt/fixit-c++11.cpp b/clang/test/FixIt/fixit-c++11.cpp index 10f4a9d0554ccc2..e635c14e0c21557 100644 --- a/clang/test/FixIt/fixit-c++11.cpp +++ b/clang/test/FixIt/fixit-c++11.cpp @@ -74,8 +74,8 @@ const char *p = "foo"bar; // expected-error {{requires a space between}} #define ord - '0' int k = '4'ord; // expected-error {{requires a space between}} -void operator"x" _y(char); // expected-error {{must be '""'}} -void operator L"" _z(char); // expected-error {{encoding prefix}} +void operator"x"_y(char); // expected-error {{must be '""'}} +void operator L""_z(char); // expected-error {{encoding prefix}} void operator "x" "y" U"z" ""_whoops "z" "y"(char); // expected-error {{must be '""'}} void f() { diff --git a/clang/test/Parser/cxx11-user-defined-literals.cpp b/clang/test/Parser/cxx11-user-defined-literals.cpp index cdd06729efc39a7..27a7181bc9f9170 100644 --- a/clang/test/Parser/cxx11-user-defined-literals.cpp +++ b/clang/test/Parser/cxx11-user-defined-literals.cpp @@ -39,19 +39,19 @@ int cake() __attribute__((availability(macosx, unavailable, message = "is a lie" #endif // But they can appear in expressions. -constexpr char operator"" _id(char c) { return c; } -constexpr wchar_t operator"" _id(wchar_t c) { return c; } -constexpr char16_t operator"" _id(char16_t c) { return c; } -constexpr char32_t operator"" _id(char32_t c) { return c; } +constexpr char operator""_id(char c) { return c; } +constexpr wchar_t operator""_id(wchar_t c) { return c; } +constexpr char16_t operator""_id(char16_t c) { return c; } +constexpr char32_t operator""_id(char32_t c) { return c; } using size_t = decltype(sizeof(int)); -constexpr const char operator"" _id(const char *p, size_t n) { return *p; } -constexpr const wchar_t operator"" _id(const wchar_t *p, size_t n) { return *p; } -constexpr const char16_t operator"" _id(const char16_t *p, size_t n) { return *p; } -constexpr const char32_t operator"" _id(const char32_t *p, size_t n) { return *p; } +constexpr const char operator""_id(const char *p, size_t n) { return *p; } +constexpr const wchar_t operator""_id(const wchar_t *p, size_t n) { return *p; } +constexpr const char16_t operator""_id(const char16_t *p, size_t n) { return *p; } +constexpr const char32_t operator""_id(const char32_t *p, size_t n) { return *p; } -constexpr unsigned long long operator"" _id(unsigned long long n) { return n; } -constexpr long double operator"" _id(long double d) { return d; } +constexpr unsigned long long operator""_id(unsigned long long n) { return n; } +constexpr long double operator""_id(long double d) { return d; } template struct S {}; S<"a"_id> sa; @@ -98,19 +98,22 @@ _no_such_suffix; // expected-error {{'operator""_no_such_suffix'}} // is "" in translation phase 7. void operator "\ " _foo(unsigned long long); // ok +// expected-warning@-1{{identifier '_foo' preceded by whitespace in a literal operator declaration is deprecated}} void operator R"xyzzy()xyzzy" _foo(long double); // ok +// expected-warning@-1{{identifier '_foo' preceded by whitespace in a literal operator declaration is deprecated}} void operator"" "" R"()" "" _foo(const char *); // ok +// expected-warning@-1{{identifier '_foo' preceded by whitespace}} void operator ""_no_space(const char *); // ok // Ensure we diagnose the bad cases. -void operator "\0" _non_empty(const char *); // expected-error {{must be '""'}} -void operator L"" _not_char(const char *); // expected-error {{cannot have an encoding prefix}} +void operator "\0"_non_empty(const char *); // expected-error {{must be '""'}} +void operator L""_not_char(const char *); // expected-error {{cannot have an encoding prefix}} void operator "" "" U"" // expected-error {{cannot have an encoding prefix}} -"" _also_not_char(const char *); +""_also_not_char(const char *); void operator "" u8"" "\u0123" "hello"_all_of_the_things ""(const char*); // expected-error {{must be '""'}} // Make sure we treat UCNs and UTF-8 as equivalent. diff --git a/clang/test/SemaCXX/cxx11-user-defined-literals-unused.cpp b/clang/test/SemaCXX/cxx11-user-defined-literals-unused.cpp index cd93ffbf21edf4a..cf95ae7de98e948 100644 --- a/clang/test/SemaCXX/cxx11-user-defined-literals-unused.cpp +++ b/clang/test/SemaCXX/cxx11-user-defined-literals-unused.cpp @@ -1,8 +1,8 @@ // RUN: %clang_cc1 -std=c++11 -verify %s -Wunused namespace { -double operator"" _x(long double value) { return double(value); } -int operator"" _ii(long double value) { return int(value); } // expected-warning {{not needed and will not be emitted}} +double operator""_x(long double value) { return double(value); } +int operator""_ii(long double value) { return int(value); } // expected-warning {{not needed and will not be emitted}} } namespace rdar13589856 { diff --git a/clang/test/SemaCXX/cxx11-user-defined-literals.cpp b/clang/test/SemaCXX/cxx11-user-defined-literals.cpp index b5d4d9976c1372f..bdf88ee01c3a121 100644 --- a/clang/test/SemaCXX/cxx11-user-defined-literals.cpp +++ b/clang/test/SemaCXX/cxx11-user-defined-literals.cpp @@ -6,18 +6,18 @@ enum class LitKind { CharStr, WideStr, Char16Str, Char32Str, Integer, Floating, Raw, Template }; -constexpr LitKind operator"" _kind(char p) { return LitKind::Char; } -constexpr LitKind operator"" _kind(wchar_t p) { return LitKind::WideChar; } -constexpr LitKind operator"" _kind(char16_t p) { return LitKind::Char16; } -constexpr LitKind operator"" _kind(char32_t p) { return LitKind::Char32; } -constexpr LitKind operator"" _kind(const char *p, size_t n) { return LitKind::CharStr; } -constexpr LitKind operator"" _kind(const wchar_t *p, size_t n) { return LitKind::WideStr; } -constexpr LitKind operator"" _kind(const char16_t *p, size_t n) { return LitKind::Char16Str; } -constexpr LitKind operator"" _kind(const char32_t *p, size_t n) { return LitKind::Char32Str; } -constexpr LitKind operator"" _kind(unsigned long long n) { return LitKind::Integer; } -constexpr LitKind operator"" _kind(long double n) { return LitKind::Floating; } -constexpr LitKind operator"" _kind2(const char *p) { return LitKind::Raw; } -template constexpr LitKind operator"" _kind3() { return LitKind::Template; } +constexpr LitKind operator""_kind(char p) { return LitKind::Char; } +constexpr LitKind operator""_kind(wchar_t p) { return LitKind::WideChar; } +constexpr LitKind operator""_kind(char16_t p) { return LitKind::Char16; } +constexpr LitKind operator""_kind(char32_t p) { return LitKind::Char32; } +constexpr LitKind operator""_kind(const char *p, size_t n) { return LitKind::CharStr; } +constexpr LitKind operator""_kind(const wchar_t *p, size_t n) { return LitKind::WideStr; } +constexpr LitKind operator""_kind(const char16_t *p, size_t n) { return LitKind::Char16Str; } +constexpr LitKind operator""_kind(const char32_t *p, size_t n) { return LitKind::Char32Str; } +constexpr LitKind operator""_kind(unsigned long long n) { return LitKind::Integer; } +constexpr LitKind operator""_kind(long double n) { return LitKind::Floating; } +constexpr LitKind operator""_kind2(const char *p) { return LitKind::Raw; } +template constexpr LitKind operator""_kind3() { return LitKind::Template; } static_assert('x'_kind == LitKind::Char, ""); static_assert(L'x'_kind == LitKind::WideChar, ""); @@ -41,7 +41,7 @@ static_assert(4e6_kind3 == LitKind::Template, ""); constexpr const char *fractional_digits_impl(const char *p) { return *p == '.' ? p + 1 : *p ? fractional_digits_impl(p + 1) : 0; } -constexpr const char *operator"" _fractional_digits(const char *p) { +constexpr const char *operator""_fractional_digits(const char *p) { return fractional_digits_impl(p) ?: p; } constexpr bool streq(const char *p, const char *q) { @@ -56,57 +56,57 @@ static_assert(streq(1e+97_fractional_digits, "1e+97"), ""); static_assert(streq(0377_fractional_digits, "0377"), ""); static_assert(streq(0377.5_fractional_digits, "5"), ""); -int operator"" _ambiguous(char); // expected-note {{candidate}} +int operator""_ambiguous(char); // expected-note {{candidate}} namespace N { - void *operator"" _ambiguous(char); // expected-note {{candidate}} + void *operator""_ambiguous(char); // expected-note {{candidate}} } using namespace N; int k = 'x'_ambiguous; // expected-error {{ambiguous}} -int operator"" _deleted(unsigned long long) = delete; // expected-note {{here}} +int operator""_deleted(unsigned long long) = delete; // expected-note {{here}} int m = 42_deleted; // expected-error {{attempt to use a deleted}} namespace Using { namespace M { - int operator"" _using(char); + int operator""_using(char); } int k1 = 'x'_using; // expected-error {{no matching literal operator for call to 'operator""_using'}} - using M::operator "" _using; + using M::operator ""_using; int k2 = 'x'_using; } namespace AmbiguousRawTemplate { - int operator"" _ambig1(const char *); // expected-note {{candidate}} - template int operator"" _ambig1(); // expected-note {{candidate}} + int operator""_ambig1(const char *); // expected-note {{candidate}} + template int operator""_ambig1(); // expected-note {{candidate}} int k1 = 123_ambig1; // expected-error {{call to 'operator""_ambig1' is ambiguous}} namespace Inner { - template int operator"" _ambig2(); // expected-note 3{{candidate}} + template int operator""_ambig2(); // expected-note 3{{candidate}} } - int operator"" _ambig2(const char *); // expected-note 3{{candidate}} - using Inner::operator"" _ambig2; + int operator""_ambig2(const char *); // expected-note 3{{candidate}} + using Inner::operator""_ambig2; int k2 = 123_ambig2; // expected-error {{call to 'operator""_ambig2' is ambiguous}} namespace N { - using Inner::operator"" _ambig2; + using Inner::operator""_ambig2; int k3 = 123_ambig2; // ok - using AmbiguousRawTemplate::operator"" _ambig2; + using AmbiguousRawTemplate::operator""_ambig2; int k4 = 123_ambig2; // expected-error {{ambiguous}} namespace M { - template int operator"" _ambig2(); + template int operator""_ambig2(); int k5 = 123_ambig2; // ok } - int operator"" _ambig2(unsigned long long); + int operator""_ambig2(unsigned long long); int k6 = 123_ambig2; // ok int k7 = 123._ambig2; // expected-error {{ambiguous}} @@ -121,7 +121,7 @@ template constexpr unsigned hash(unsigned a) { return hash(mash(a ^ mash(C))); } template struct constant { constexpr static T value = v; }; -template constexpr unsigned operator"" _hash() { +template constexpr unsigned operator""_hash() { return constant(0)>::value; } static_assert(0x1234_hash == 0x103eff5e, ""); @@ -129,7 +129,7 @@ static_assert(hash<'0', 'x', '1', '2', '3', '4'>(0) == 0x103eff5e, ""); // Functions and literal suffixes go in separate namespaces. namespace Namespace { - template int operator"" _x(); + template int operator""_x(); int k = _x(); // expected-error {{undeclared identifier '_x'}} int _y(unsigned long long); @@ -138,7 +138,7 @@ namespace Namespace { namespace PR14950 { template<...> // expected-error {{expected template parameter}} - int operator"" _b(); // expected-error {{no function template matches function template specialization}} + int operator""_b(); // expected-error {{no function template matches function template specialization}} int main() { return 0_b; } // expected-error {{no matching literal operator for call to 'operator""_b'}} } diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index ae331055c52b2e8..fef4674d178412e 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -158,17 +158,17 @@ int i3 = f1(f1(f1(&f1, &f1), f1(&f1, &f1), f1(f1(&f1, &f1), &f1))); namespace user_defined_literal { -consteval int operator"" _test(unsigned long long i) { +consteval int operator""_test(unsigned long long i) { // expected-note@-1+ {{declared here}} return 0; } int i = 0_test; -auto ptr = &operator"" _test; +auto ptr = &operator""_test; // expected-error@-1 {{take address}} -consteval auto operator"" _test1(unsigned long long i) { +consteval auto operator""_test1(unsigned long long i) { return &f_eval; } diff --git a/clang/test/SemaCXX/cxx98-compat.cpp b/clang/test/SemaCXX/cxx98-compat.cpp index 3ce69d6908c5b22..28547d42c64902d 100644 --- a/clang/test/SemaCXX/cxx98-compat.cpp +++ b/clang/test/SemaCXX/cxx98-compat.cpp @@ -84,7 +84,7 @@ struct DelayedDefaultArgumentParseInitList { } }; -int operator"" _hello(const char *); // expected-warning {{literal operators are incompatible with C++98}} +int operator""_hello(const char *); // expected-warning {{literal operators are incompatible with C++98}} enum EnumFixed : int { // expected-warning {{enumeration types with a fixed underlying type are incompatible with C++98}} }; diff --git a/clang/test/SemaCXX/literal-operators.cpp b/clang/test/SemaCXX/literal-operators.cpp index 067e151606202ee..2a41e048914b786 100644 --- a/clang/test/SemaCXX/literal-operators.cpp +++ b/clang/test/SemaCXX/literal-operators.cpp @@ -3,46 +3,46 @@ #include struct tag { - void operator "" _tag_bad (const char *); // expected-error {{literal operator 'operator""_tag_bad' must be in a namespace or global scope}} - friend void operator "" _tag_good (const char *); + void operator ""_tag_bad (const char *); // expected-error {{literal operator 'operator""_tag_bad' must be in a namespace or global scope}} + friend void operator ""_tag_good (const char *); }; -namespace ns { void operator "" _ns_good (const char *); } +namespace ns { void operator ""_ns_good (const char *); } // Check extern "C++" declarations -extern "C++" void operator "" _extern_good (const char *); -extern "C++" { void operator "" _extern_good (const char *); } +extern "C++" void operator ""_extern_good (const char *); +extern "C++" { void operator ""_extern_good (const char *); } -void fn () { void operator "" _fn_good (const char *); } +void fn () { void operator ""_fn_good (const char *); } // One-param declarations (const char * was already checked) -void operator "" _good (char); -void operator "" _good (wchar_t); -void operator "" _good (char16_t); -void operator "" _good (char32_t); -void operator "" _good (unsigned long long); -void operator "" _good (long double); +void operator ""_good (char); +void operator ""_good (wchar_t); +void operator ""_good (char16_t); +void operator ""_good (char32_t); +void operator ""_good (unsigned long long); +void operator ""_good (long double); // Two-param declarations -void operator "" _good (const char *, size_t); -void operator "" _good (const wchar_t *, size_t); -void operator "" _good (const char16_t *, size_t); -void operator "" _good (const char32_t *, size_t); +void operator ""_good (const char *, size_t); +void operator ""_good (const wchar_t *, size_t); +void operator ""_good (const char16_t *, size_t); +void operator ""_good (const char32_t *, size_t); // Check typedef and array equivalences -void operator "" _good (const char[]); +void operator ""_good (const char[]); typedef const char c; -void operator "" _good (c*); +void operator ""_good (c*); // Check extra cv-qualifiers -void operator "" _cv_good (volatile const char *, const size_t); // expected-error {{invalid literal operator parameter type 'const volatile char *', did you mean 'const char *'?}} +void operator ""_cv_good (volatile const char *, const size_t); // expected-error {{invalid literal operator parameter type 'const volatile char *', did you mean 'const char *'?}} // Template declaration -template void operator "" _good (); +template void operator ""_good (); -template void operator "" _invalid(); // expected-error {{template parameter list for literal operator must be either 'char...' or 'typename T, T...'}} -template void operator "" _invalid(); // expected-error {{template parameter list for literal operator must be either 'char...' or 'typename T, T...'}} -template void operator "" _invalid(); // expected-error {{template parameter list for literal operator must be either 'char...' or 'typename T, T...'}} +template void operator ""_invalid(); // expected-error {{template parameter list for literal operator must be either 'char...' or 'typename T, T...'}} +template void operator ""_invalid(); // expected-error {{template parameter list for literal operator must be either 'char...' or 'typename T, T...'}} +template void operator ""_invalid(); // expected-error {{template parameter list for literal operator must be either 'char...' or 'typename T, T...'}} _Complex float operator""if(long double); // expected-warning {{reserved}} _Complex float test_if_1() { return 2.0f + 1.5if; }; diff --git a/clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp b/clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp index ee5b0c47b9ffcd2..61b08954c40b586 100644 --- a/clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp +++ b/clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wsystem-headers -isystem %S %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -isystem %S %s #include diff --git a/clang/test/SemaCXX/reserved-identifier.cpp b/clang/test/SemaCXX/reserved-identifier.cpp index eaa5fe8330337e7..a3e6d8ead61fd8a 100644 --- a/clang/test/SemaCXX/reserved-identifier.cpp +++ b/clang/test/SemaCXX/reserved-identifier.cpp @@ -76,7 +76,8 @@ namespace { int _barbatruc; // no-warning } -long double operator"" _BarbeBleue(long double) // expected-warning {{identifier '_BarbeBleue' is reserved because it starts with '_' followed by a capital letter}} +long double operator"" _BarbeBleue(long double) // expected-warning {{identifier '_BarbeBleue' is reserved because it starts with '_' followed by a capital letter}}\ + // expected-warning {{identifier '_BarbeBleue' preceded by whitespace in a literal operator declaration is deprecated}} { return 0.; } @@ -86,10 +87,11 @@ long double operator""_SacreBleu(long double) // no-warning return 0.; } -long double sacrebleu = operator"" _SacreBleu(1.2); // expected-warning {{identifier '_SacreBleu' is reserved because it starts with '_' followed by a capital letter}} +long double sacrebleu = operator"" _SacreBleu(1.2); // expected-warning {{identifier '_SacreBleu' is reserved because it starts with '_' followed by a capital letter}} \ + // expected-warning {{identifier '_SacreBleu' preceded by whitespace in a literal operator declaration is deprecated}} long double sangbleu = operator""_SacreBleu(1.2); // no-warning -void operator"" _lowercase(unsigned long long); // no-warning +void operator"" _lowercase(unsigned long long); // expected-warning {{identifier '_lowercase' preceded by whitespace in a literal operator declaration is deprecated}} void operator""_lowercase(unsigned long long); // no-warning struct _BarbeRouge { // expected-warning {{identifier '_BarbeRouge' is reserved because it starts with '_' followed by a capital letter}} diff --git a/clang/test/SemaCXX/warn-xor-as-pow.cpp b/clang/test/SemaCXX/warn-xor-as-pow.cpp index 88719bd1a9d7757..ade977f97e43665 100644 --- a/clang/test/SemaCXX/warn-xor-as-pow.cpp +++ b/clang/test/SemaCXX/warn-xor-as-pow.cpp @@ -19,10 +19,10 @@ #define flexor 7 #ifdef __cplusplus -constexpr long long operator"" _xor(unsigned long long v) { return v; } +constexpr long long operator""_xor(unsigned long long v) { return v; } -constexpr long long operator"" _0b(unsigned long long v) { return v; } -constexpr long long operator"" _0X(unsigned long long v) { return v; } +constexpr long long operator""_0b(unsigned long long v) { return v; } +constexpr long long operator""_0X(unsigned long long v) { return v; } #else #define xor ^ // iso646.h #endif