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.
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>;
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;
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
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;
}
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.
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)
}
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);
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
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}}
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}}