[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