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


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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to