rZhBoYao updated this revision to Diff 530292.
rZhBoYao added a comment.

Addressed comments.
Thanks for letting me know how to structure tests for DRs.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152632/new/

https://reviews.llvm.org/D152632

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/drs/dr17xx.cpp
  clang/test/CXX/drs/dr25xx.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
  clang/test/Parser/cxx0x-literal-operators.cpp
  clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
  clang/www/cxx_dr_status.html

Index: clang/www/cxx_dr_status.html
===================================================================
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -14933,7 +14933,7 @@
     <td><a href="https://cplusplus.github.io/CWG/issues/2521.html";>2521</a></td>
     <td>DR</td>
     <td>User-defined literals and reserved identifiers</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="unreleased" align="center">Clang 17</td>
   </tr>
   <tr class="open" id="2522">
     <td><a href="https://cplusplus.github.io/CWG/issues/2522.html";>2522</a></td>
Index: clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
===================================================================
--- clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
+++ clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
@@ -2,4 +2,4 @@
 
 #include <no-warn-user-defined-literals-in-system-headers.h>
 
-void operator "" bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator "" bar(long double); // expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
Index: clang/test/Parser/cxx0x-literal-operators.cpp
===================================================================
--- clang/test/Parser/cxx0x-literal-operators.cpp
+++ clang/test/Parser/cxx0x-literal-operators.cpp
@@ -3,6 +3,6 @@
 void operator "" (const char *); // expected-error {{expected identifier}}
 void operator "k" foo(const char *); // \
   expected-error {{string literal after 'operator' must be '""'}} \
-  expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+  expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
 void operator "" tester (const char *); // \
-  expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+  expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
Index: clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
===================================================================
--- clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
+++ clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++11 -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}}
-void operator "" wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+void operator "" wibble(const char *); // expected-warning {{user-defined literal suffixes containing '__' or not starting with '_' are reserved; no literal will invoke this operator}}
+void operator "" wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes containing '__' or not starting with '_' are reserved; no literal will invoke this operator}}
 
 template<typename T>
 void f() {
Index: clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
===================================================================
--- clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
+++ clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
 
-void operator "" p31(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator "" p31(long double); // expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
 void operator "" _p31(long double);
-long double operator "" pi(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+long double operator "" pi(long double); // expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
 
 float hexfloat = 0x1p31; // allow hexfloats
Index: clang/test/CXX/drs/dr25xx.cpp
===================================================================
--- clang/test/CXX/drs/dr25xx.cpp
+++ clang/test/CXX/drs/dr25xx.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -Wdeprecated-literal-operator
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -Wdeprecated
 
 namespace dr2516 { // dr2516: yes
                    // NB: reusing 1482 test
@@ -108,3 +109,20 @@
   // expected-note@-2{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
 
 }
+
+namespace dr2521 { // dr2521: 17
+
+// expected-warning@+2{{identifier '_π___' preceded by space(s) in the literal operator declaration is deprecated}}
+// expected-warning@+1{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
+decltype(sizeof 0) operator ""  _\u{3C0}___(long double);
+
+template <char... Chars> consteval auto
+operator""       _div() { return (... / (Chars - '0')); }
+// expected-warning@-1{{identifier '_div' preceded by space(s) in the literal operator declaration is deprecated}}
+
+} // namespace dr2521
+
+// expected-warning@+1{{identifier '_π___' preceded by space(s) in the literal operator declaration is deprecated}}
+using dr2521::operator"" _\u{3C0}___, dr2521::operator""_div;
+
+[[maybe_unused]] constexpr auto div = 841_div;
Index: clang/test/CXX/drs/dr17xx.cpp
===================================================================
--- clang/test/CXX/drs/dr17xx.cpp
+++ clang/test/CXX/drs/dr17xx.cpp
@@ -127,7 +127,7 @@
 #if __cplusplus >= 201103L
   float operator ""_E(const char *);
   // expected-error@+2 {{invalid suffix on literal; C++11 requires a space between literal and identifier}}
-  // expected-warning@+1 {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+  // expected-warning@+1 {{user-defined literal suffixes containing '__' or not starting with '_' are reserved; no literal will invoke this operator}}
   float operator ""E(const char *);
 #endif
 }
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -501,10 +501,16 @@
     IdentifierInfo *II = Name.Identifier;
     ReservedIdentifierStatus Status = II->isReserved(PP.getLangOpts());
     SourceLocation Loc = Name.getEndLoc();
-    if (isReservedInAllContexts(Status) &&
-        !PP.getSourceManager().isInSystemHeader(Loc)) {
-      Diag(Loc, diag::warn_reserved_extern_symbol)
-          << II << static_cast<int>(Status)
+    if (!PP.getSourceManager().isInSystemHeader(Loc)) {
+      if (isReservedInAllContexts(Status)) {
+        Diag(Loc, diag::warn_reserved_extern_symbol)
+            << II << static_cast<int>(Status)
+            << FixItHint::CreateReplacement(
+                   Name.getSourceRange(),
+                   (StringRef("operator\"\"") + II->getName()).str());
+      }
+      Diag(Loc, diag::warn_deprecated_literal_operator_id)
+          << II->getName()
           << FixItHint::CreateReplacement(
                  Name.getSourceRange(),
                  (StringRef("operator\"\"") + II->getName()).str());
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -16445,11 +16445,13 @@
 
   StringRef LiteralName
     = FnDecl->getDeclName().getCXXLiteralIdentifier()->getName();
-  if (LiteralName[0] != '_' &&
+  if ((LiteralName[0] != '_' || LiteralName.contains("__")) &&
       !getSourceManager().isInSystemHeader(FnDecl->getLocation())) {
-    // C++11 [usrlit.suffix]p1:
-    //   Literal suffix identifiers that do not start with an underscore
-    //   are reserved for future standardization.
+    // C++23 [usrlit.suffix]p1:
+    //   Literal suffix identifiers that do not start with an underscore are
+    //   reserved for future standardization. Literal suffix identifiers that
+    //   contain a double underscore __ are reserved for use by C++
+    //   implementations.
     Diag(FnDecl->getLocation(), diag::warn_user_literal_reserved)
       << StringLiteralParser::isValidUDSuffix(getLangOpts(), LiteralName);
   }
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -406,6 +406,9 @@
   "it starts with '_' followed by a capital letter|"
   "it contains '__'}1">,
   InGroup<ReservedIdentifier>, DefaultIgnore;
+def warn_deprecated_literal_operator_id: Warning<
+  "identifier '%0' preceded by space(s) in the literal operator declaration "
+  "is deprecated">, InGroup<DeprecatedLiteralOperator>, DefaultIgnore;
 def warn_reserved_module_name : Warning<
   "%0 is a reserved name for a module">, InGroup<ReservedModuleIdentifier>;
 
@@ -9263,7 +9266,7 @@
   "string literal operator templates are a GNU extension">,
   InGroup<GNUStringLiteralOperatorTemplate>;
 def warn_user_literal_reserved : Warning<
-  "user-defined literal suffixes not starting with '_' are reserved"
+  "user-defined literal suffixes containing '__' or not starting with '_' are reserved"
   "%select{; no literal will invoke this operator|}0">,
   InGroup<UserDefinedLiterals>;
 
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -183,6 +183,7 @@
 def DeprecatedCopyWithUserProvidedDtor : DiagGroup<"deprecated-copy-with-user-provided-dtor">;
 def DeprecatedCopy : DiagGroup<"deprecated-copy", [DeprecatedCopyWithUserProvidedCopy]>;
 def DeprecatedCopyWithDtor : DiagGroup<"deprecated-copy-with-dtor", [DeprecatedCopyWithUserProvidedDtor]>;
+def DeprecatedLiteralOperator : DiagGroup<"deprecated-literal-operator">;
 // For compatibility with GCC.
 def : DiagGroup<"deprecated-copy-dtor", [DeprecatedCopyWithDtor]>;
 def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
@@ -219,6 +220,7 @@
                                           DeprecatedEnumFloatConversion,
                                           DeprecatedBuiltins,
                                           DeprecatedIncrementBool,
+                                          DeprecatedLiteralOperator,
                                           DeprecatedPragma,
                                           DeprecatedRegister,
                                           DeprecatedThisCapture,
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -136,6 +136,22 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 - Implemented `DR2397 <https://wg21.link/CWG2397>`_ which allows ``auto`` specifier for pointers
   and reference to arrays.
+- Implemented `CWG2521 <https://wg21.link/CWG2521>`_ which reserves using ``__`` in user defined literal suffixes
+  for C++ implementations, and deprecates literal operator function declarations using an identifier.
+  Taught ``-Wuser-defined-literals`` for the former, on by default, and added ``-Wdeprecated-literal-operator``
+  for the latter, off by default.
+
+  .. code-block:: c++
+
+    // What follows is warned by -Wuser-defined-literals
+    // albeit "ill-formed, no diagnostic required".
+    // Its behavior is undefined, [reserved.names.general]p2.
+    string operator ""__i18n(const char*, std::size_t);
+
+    // Let's assume this is not in the global namespace.
+    // -Wdeprecated-literal-operator whines about extra spaces.
+    string operator "" _i18n(const char*, std::size_t);
+    //                ^ an extra space
 
 C Language Changes
 ------------------
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to