From: Richard Smith Date: Wed, 6 Oct 2021 21:11:32 +0000 (-0700) Subject: PR50644: Do not warn on a declaration of `operator"" _foo`. X-Git-Tag: upstream/15.0.7~29391 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7063b76b02484f93104f1c79496ad216b9bf5b87;p=platform%2Fupstream%2Fllvm.git 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. --- diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index d620138..803fec8 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; diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 6788f21..57d84f2 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(this) || isTemplateParameter()) return ReservedIdentifierStatus::NotReserved; diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index b53ff12..e77b389 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 610c64d..2186eec 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 1b4c49d..8e2a549 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(Status) diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 529f814..c83ada8 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(Status); diff --git a/clang/test/Sema/reserved-identifier.c b/clang/test/Sema/reserved-identifier.c index 2ee7fc6..746b477 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 1d3e0f9..56fa387 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}}