[clang] 7063b76 - PR50644: Do not warn on a declaration of `operator"" _foo`.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 6 15:13:45 PDT 2021


Author: Richard Smith
Date: 2021-10-06T15:13:05-07:00
New Revision: 7063b76b02484f93104f1c79496ad216b9bf5b87

URL: https://github.com/llvm/llvm-project/commit/7063b76b02484f93104f1c79496ad216b9bf5b87
DIFF: https://github.com/llvm/llvm-project/commit/7063b76b02484f93104f1c79496ad216b9bf5b87.diff

LOG: PR50644: Do not warn on a declaration of `operator"" _foo`.

Also do not warn on `#define _foo` or `#undef _foo`.

Only global scope names starting with _[a-z] are reserved, not the use
of such an identifier in any other context.

Added: 
    clang/test/SemaCXX/reserved-identifier.cpp

Modified: 
    clang/include/clang/Basic/IdentifierTable.h
    clang/lib/AST/Decl.cpp
    clang/lib/Lex/PPDirectives.cpp
    clang/lib/Sema/SemaCodeComplete.cpp
    clang/lib/Sema/SemaExprCXX.cpp
    clang/lib/Sema/SemaStmt.cpp
    clang/test/Sema/reserved-identifier.c

Removed: 
    clang/test/Sema/reserved-identifier.cpp


################################################################################
diff  --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h
index d62013812556..803fec8df30c 100644
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ b/clang/include/clang/Basic/IdentifierTable.h
@@ -48,6 +48,21 @@ enum class ReservedIdentifierStatus {
   ContainsDoubleUnderscore,
 };
 
+/// Determine whether an identifier is reserved for use as a name at global
+/// scope. Such identifiers might be implementation-specific global functions
+/// or variables.
+inline bool isReservedAtGlobalScope(ReservedIdentifierStatus Status) {
+  return Status != ReservedIdentifierStatus::NotReserved;
+}
+
+/// Determine whether an identifier is reserved in all contexts. Such
+/// identifiers might be implementation-specific keywords or macros, for
+/// example.
+inline bool isReservedInAllContexts(ReservedIdentifierStatus Status) {
+  return Status != ReservedIdentifierStatus::NotReserved &&
+         Status != ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope;
+}
+
 /// A simple pair of identifier info and location.
 using IdentifierLocPair = std::pair<IdentifierInfo *, SourceLocation>;
 

diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 6788f2132fbc..57d84f2c3439 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1088,7 +1088,7 @@ NamedDecl::isReserved(const LangOptions &LangOpts) const {
     return ReservedIdentifierStatus::NotReserved;
 
   ReservedIdentifierStatus Status = II->isReserved(LangOpts);
-  if (Status == ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope) {
+  if (isReservedAtGlobalScope(Status) && !isReservedInAllContexts(Status)) {
     // Check if we're at TU level or not.
     if (isa<ParmVarDecl>(this) || isTemplateParameter())
       return ReservedIdentifierStatus::NotReserved;

diff  --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index b53ff12bbaa6..e77b3898e0df 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -129,7 +129,7 @@ static bool isForModuleBuilding(Module *M, StringRef CurrentModule,
 
 static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) {
   const LangOptions &Lang = PP.getLangOpts();
-  if (II->isReserved(Lang) != ReservedIdentifierStatus::NotReserved) {
+  if (isReservedInAllContexts(II->isReserved(Lang))) {
     // list from:
     // - https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html
     // - https://docs.microsoft.com/en-us/cpp/c-runtime-library/security-features-in-the-crt?view=msvc-160
@@ -183,7 +183,7 @@ static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) {
 static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II) {
   const LangOptions &Lang = PP.getLangOpts();
   // Do not warn on keyword undef.  It is generally harmless and widely used.
-  if (II->isReserved(Lang) != ReservedIdentifierStatus::NotReserved)
+  if (isReservedInAllContexts(II->isReserved(Lang)))
     return MD_ReservedMacro;
   return MD_NoWarn;
 }

diff  --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 610c64d1521b..2186eec955bf 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -743,9 +743,7 @@ getRequiredQualification(ASTContext &Context, const DeclContext *CurContext,
 static bool shouldIgnoreDueToReservedName(const NamedDecl *ND, Sema &SemaRef) {
   ReservedIdentifierStatus Status = ND->isReserved(SemaRef.getLangOpts());
   // Ignore reserved names for compiler provided decls.
-  if ((Status != ReservedIdentifierStatus::NotReserved) &&
-      (Status != ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope) &&
-      ND->getLocation().isInvalid())
+  if (isReservedInAllContexts(Status) && ND->getLocation().isInvalid())
     return true;
 
   // For system headers ignore only double-underscore names.

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 1b4c49d7880b..8e2a549c7a9c 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -494,7 +494,7 @@ bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
     IdentifierInfo *II = Name.Identifier;
     ReservedIdentifierStatus Status = II->isReserved(PP.getLangOpts());
     SourceLocation Loc = Name.getEndLoc();
-    if (Status != ReservedIdentifierStatus::NotReserved &&
+    if (isReservedInAllContexts(Status) &&
         !PP.getSourceManager().isInSystemHeader(Loc)) {
       Diag(Loc, diag::warn_reserved_extern_symbol)
           << II << static_cast<int>(Status)

diff  --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 529f814cb458..c83ada89d2e0 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -547,7 +547,7 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,
   }
 
   ReservedIdentifierStatus Status = TheDecl->isReserved(getLangOpts());
-  if (Status != ReservedIdentifierStatus::NotReserved &&
+  if (isReservedInAllContexts(Status) &&
       !Context.getSourceManager().isInSystemHeader(IdentLoc))
     Diag(IdentLoc, diag::warn_reserved_extern_symbol)
         << TheDecl << static_cast<int>(Status);

diff  --git a/clang/test/Sema/reserved-identifier.c b/clang/test/Sema/reserved-identifier.c
index 2ee7fc63751f..746b4775b0fe 100644
--- a/clang/test/Sema/reserved-identifier.c
+++ b/clang/test/Sema/reserved-identifier.c
@@ -16,6 +16,8 @@ void foo(unsigned int _Reserved) { // expected-warning {{identifier '_Reserved'
   goto __reserved;                 // expected-warning {{identifier '__reserved' is reserved because it starts with '__'}}
 __reserved: // expected-warning {{identifier '__reserved' is reserved because it starts with '__'}}
             ;
+  goto _not_reserved;
+_not_reserved: ;
 }
 
 void foot(unsigned int _not_reserved) {} // no-warning

diff  --git a/clang/test/Sema/reserved-identifier.cpp b/clang/test/SemaCXX/reserved-identifier.cpp
similarity index 93%
rename from clang/test/Sema/reserved-identifier.cpp
rename to clang/test/SemaCXX/reserved-identifier.cpp
index 1d3e0f9f0043..56fa3873359b 100644
--- a/clang/test/Sema/reserved-identifier.cpp
+++ b/clang/test/SemaCXX/reserved-identifier.cpp
@@ -89,6 +89,9 @@ long double operator""_SacreBleu(long double) // no-warning
 long double sacrebleu = operator"" _SacreBleu(1.2); // expected-warning {{identifier '_SacreBleu' is reserved because it starts with '_' followed by a capital letter}}
 long double sangbleu = operator""_SacreBleu(1.2);   // no-warning
 
+void operator"" _lowercase(unsigned long long); // no-warning
+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}}
 } p;
 struct _BarbeNoire { // expected-warning {{identifier '_BarbeNoire' is reserved because it starts with '_' followed by a capital letter}}
@@ -97,3 +100,8 @@ struct _BarbeNoire { // expected-warning {{identifier '_BarbeNoire' is reserved
 struct Any {
   friend void _barbegrise(); // expected-warning {{identifier '_barbegrise' is reserved because it starts with '_' at global scope}}
 };
+
+#define _not_reserved
+#define _Reserved // expected-warning {{macro name is a reserved identifier}}
+#undef _not_reserved
+#undef _Reserved // expected-warning {{macro name is a reserved identifier}}


        


More information about the cfe-commits mailing list