diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5703,6 +5703,13 @@ return false; } +/// Returns true if the declaration is declared in a system header or from a +/// system macro. +static bool isFromSystemHeader(SourceManager &SM, const Decl *D) { + return SM.isInSystemHeader(D->getLocation()) || + SM.isInSystemMacro(D->getLocation()); +} + void Sema::warnOnReservedIdentifier(const NamedDecl *D) { // Avoid warning twice on the same identifier, and don't warn on redeclaration // of system decl. @@ -5710,9 +5717,10 @@ return; ReservedIdentifierStatus Status = D->isReserved(getLangOpts()); if (Status != ReservedIdentifierStatus::NotReserved && - !Context.getSourceManager().isInSystemHeader(D->getLocation())) + !isFromSystemHeader(Context.getSourceManager(), D)) { Diag(D->getLocation(), diag::warn_reserved_extern_symbol) << D << static_cast(Status); + } } Decl *Sema::ActOnDeclarator(Scope *S, Declarator &D) { diff --git a/clang/test/Sema/Inputs/reserved-identifier.h b/clang/test/Sema/Inputs/reserved-identifier.h new file mode 100644 --- /dev/null +++ b/clang/test/Sema/Inputs/reserved-identifier.h @@ -0,0 +1,4 @@ +int __i_come_from_a_system_header; // no-warning +#define __I_AM_A_SYSTEM_MACRO() // no-warning + +#define SOME_SYSTEM_MACRO() int __i_come_from_a_system_macro diff --git a/clang/test/Sema/reserved-identifier.c b/clang/test/Sema/reserved-identifier.c --- a/clang/test/Sema/reserved-identifier.c +++ b/clang/test/Sema/reserved-identifier.c @@ -1,4 +1,12 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wreserved-identifier -Wno-visibility %s +// RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only -verify -Wreserved-identifier -Wno-visibility %s + +#include + +__I_AM_A_SYSTEM_MACRO() // no-warning + +void test_system_macro_expansion() { + SOME_SYSTEM_MACRO(); // no-warning +} #define __oof foo__ // expected-warning {{macro name is a reserved identifier}} @@ -58,7 +66,7 @@ extern char *_strdup(const char *); // expected-warning {{identifier '_strdup' is reserved because it starts with '_' at global scope}} -// Don't warn on redecleration +// Don't warn on redeclaration extern char *_strdup(const char *); // no-warning void ok() {