[PATCH] D104299: Handle interactions between reserved identifier and user-defined suffixes

serge via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 15 08:05:06 PDT 2021


serge-sans-paille created this revision.
serge-sans-paille added reviewers: aaron.ballman, rsmith.
Herald added a subscriber: dexonsmith.
serge-sans-paille requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added subscribers: cfe-commits, sstefan1.
Herald added a project: clang.

According to https://eel.is/c++draft/over.literal

> double operator""_Bq(long double);  // OK: does not use the reserved identifier _­Bq ([lex.name])
> double operator"" _Bq(long double); // ill-formed, no diagnostic required: uses the reserved identifier _­Bq ([lex.name])

Obey that rule by keeping track of the operator literal name status wrt. leading whitespace.

Fix: https://bugs.llvm.org/show_bug.cgi?id=50644


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D104299

Files:
  clang/include/clang/Basic/IdentifierTable.h
  clang/lib/Basic/IdentifierTable.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/test/Sema/reserved-identifier.cpp


Index: clang/test/Sema/reserved-identifier.cpp
===================================================================
--- clang/test/Sema/reserved-identifier.cpp
+++ clang/test/Sema/reserved-identifier.cpp
@@ -81,6 +81,11 @@
   return 0.;
 }
 
+long double operator""_SacreBleue(long double) // no-warning
+{
+  return 0.;
+}
+
 struct _BarbeRouge { // expected-warning {{identifier '_BarbeRouge' is reserved because it starts with '_' followed by a capital letter}}
 } p;
 struct _BarbeNoire { // expected-warning {{identifier '_BarbeNoire' is reserved because it starts with '_' followed by a capital letter}}
Index: clang/lib/Parse/ParseExprCXX.cpp
===================================================================
--- clang/lib/Parse/ParseExprCXX.cpp
+++ clang/lib/Parse/ParseExprCXX.cpp
@@ -2644,6 +2644,7 @@
         Lexer::AdvanceToTokenCharacter(TokLocs[Literal.getUDSuffixToken()],
                                        Literal.getUDSuffixOffset(),
                                        PP.getSourceManager(), getLangOpts());
+      II->setLiteralOperatorWithoutWhitespace(true);
     } else if (Tok.is(tok::identifier)) {
       II = Tok.getIdentifierInfo();
       SuffixLoc = ConsumeToken();
Index: clang/lib/Basic/IdentifierTable.cpp
===================================================================
--- clang/lib/Basic/IdentifierTable.cpp
+++ clang/lib/Basic/IdentifierTable.cpp
@@ -285,6 +285,11 @@
   if (Name.size() <= 1)
     return ReservedIdentifierStatus::NotReserved;
 
+  // [over.literal] p8
+  llvm::errs() << Name << " isLiteralOperatorWithoutWhitespace: " << isLiteralOperatorWithoutWhitespace() << "\n";
+  if(isLiteralOperatorWithoutWhitespace())
+    return ReservedIdentifierStatus::NotReserved;
+
   // [lex.name] p3
   if (Name[0] == '_') {
 
Index: clang/include/clang/Basic/IdentifierTable.h
===================================================================
--- clang/include/clang/Basic/IdentifierTable.h
+++ clang/include/clang/Basic/IdentifierTable.h
@@ -121,7 +121,10 @@
   // True if this is a mangled OpenMP variant name.
   unsigned IsMangledOpenMPVariantName : 1;
 
-  // 28 bits left in a 64-bit word.
+  // True if this identifier is a literal operator without whitespace.
+  unsigned IsLiteralOperatorWithoutWhitespace : 1;
+
+  // 27 bits left in a 64-bit word.
 
   // Managed by the language front-end.
   void *FETokenInfo = nullptr;
@@ -134,7 +137,8 @@
         IsPoisoned(false), IsCPPOperatorKeyword(false),
         NeedsHandleIdentifier(false), IsFromAST(false), ChangedAfterLoad(false),
         FEChangedAfterLoad(false), RevertedTokenID(false), OutOfDate(false),
-        IsModulesImport(false), IsMangledOpenMPVariantName(false) {}
+        IsModulesImport(false), IsMangledOpenMPVariantName(false),
+        IsLiteralOperatorWithoutWhitespace(false) {}
 
 public:
   IdentifierInfo(const IdentifierInfo &) = delete;
@@ -378,6 +382,16 @@
   /// Set whether this is the mangled name of an OpenMP variant.
   void setMangledOpenMPVariantName(bool I) { IsMangledOpenMPVariantName = I; }
 
+  /// Determine whether this is a literal operator without whitespace
+  bool isLiteralOperatorWithoutWhitespace() const {
+    return IsLiteralOperatorWithoutWhitespace;
+  }
+
+  /// Set whether this is a literal operator without whitespace.
+  void setLiteralOperatorWithoutWhitespace(bool I) {
+    IsLiteralOperatorWithoutWhitespace = I;
+  }
+
   /// Return true if this identifier is an editor placeholder.
   ///
   /// Editor placeholders are produced by the code-completion engine and are


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D104299.352141.patch
Type: text/x-patch
Size: 3552 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210615/41e36701/attachment.bin>


More information about the cfe-commits mailing list