https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/106036
>From d4b07c7ff65ca64a5a434818ce09ecd289401340 Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Tue, 10 Sep 2024 02:35:43 +0300 Subject: [PATCH 1/2] [Clang] restrict use of attribute names reserved by the C++ standard --- clang/docs/ReleaseNotes.rst | 2 ++ .../include/clang/Basic/AttributeCommonInfo.h | 2 +- clang/include/clang/Basic/CMakeLists.txt | 5 +++ clang/include/clang/Basic/DiagnosticGroups.td | 1 + .../include/clang/Basic/DiagnosticLexKinds.td | 2 ++ clang/include/clang/Lex/Preprocessor.h | 10 +++--- clang/include/clang/Sema/CMakeLists.txt | 5 --- clang/lib/Lex/PPDirectives.cpp | 26 +++++++++++++- .../Preprocessor/macro-reserved-attrs1.cpp | 34 +++++++++++++++++++ .../Preprocessor/macro-reserved-attrs2.cpp | 34 +++++++++++++++++++ .../gn/secondary/clang/lib/Basic/BUILD.gn | 5 +-- .../gn/secondary/clang/lib/Sema/BUILD.gn | 2 +- .../llvm-project-overlay/clang/BUILD.bazel | 9 +++-- 13 files changed, 115 insertions(+), 22 deletions(-) create mode 100644 clang/test/Preprocessor/macro-reserved-attrs1.cpp create mode 100644 clang/test/Preprocessor/macro-reserved-attrs2.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 250821a9f9c45c..eecf5de3775f21 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -298,6 +298,8 @@ Improvements to Clang's diagnostics - Clang now warns for u8 character literals used in C23 with ``-Wpre-c23-compat`` instead of ``-Wpre-c++17-compat``. +- Clang now diagnoses the use of attribute names reserved by the C++ standard. (#GH92196). + Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h b/clang/include/clang/Basic/AttributeCommonInfo.h index 5f024b4b5fd782..15e2685e049d9c 100644 --- a/clang/include/clang/Basic/AttributeCommonInfo.h +++ b/clang/include/clang/Basic/AttributeCommonInfo.h @@ -61,7 +61,7 @@ class AttributeCommonInfo { }; enum Kind { #define PARSED_ATTR(NAME) AT_##NAME, -#include "clang/Sema/AttrParsedAttrList.inc" +#include "clang/Basic/AttrParsedAttrList.inc" #undef PARSED_ATTR NoSemaHandlerAttribute, IgnoredAttribute, diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index f069f4fc118f27..bcc34e86385926 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -31,6 +31,11 @@ clang_tablegen(AttrList.inc -gen-clang-attr-list SOURCE Attr.td TARGET ClangAttrList) +clang_tablegen(AttrParsedAttrList.inc -gen-clang-attr-parsed-attr-list + -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + SOURCE Attr.td + TARGET ClangAttrParsedAttrList) + clang_tablegen(AttrSubMatchRulesList.inc -gen-clang-attr-subject-match-rule-list -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ SOURCE Attr.td diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 116ce7a04f66f7..f04afce2da5a8c 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -751,6 +751,7 @@ def AmbiguousMacro : DiagGroup<"ambiguous-macro">; def KeywordAsMacro : DiagGroup<"keyword-macro">; def ReservedIdAsMacro : DiagGroup<"reserved-macro-identifier">; def ReservedIdAsMacroAlias : DiagGroup<"reserved-id-macro", [ReservedIdAsMacro]>; +def ReservedAttributeIdentifier : DiagGroup<"reserved-attribute-identifier">; def RestrictExpansionMacro : DiagGroup<"restrict-expansion">; def FinalMacro : DiagGroup<"final-macro">; diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index fc14bb6aa21651..7e1964b6284c83 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -407,6 +407,8 @@ def warn_pp_macro_hides_keyword : Extension< def warn_pp_macro_is_reserved_id : Warning< "macro name is a reserved identifier">, DefaultIgnore, InGroup<ReservedIdAsMacro>; +def warn_pp_macro_is_reserved_attribute_id : Warning< + "%0 is a reserved attribute identifier">, InGroup<ReservedAttributeIdentifier>; def warn_pp_objc_macro_redef_ignored : Warning< "ignoring redefinition of Objective-C qualifier macro">, InGroup<DiagGroup<"objc-macro-redefinition">>; diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 1307659e27d137..1e1d5ce0de48dc 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -2286,6 +2286,11 @@ class Preprocessor { } } + /// Determine whether the next preprocessor token to be + /// lexed is a '('. If so, consume the token and return true, if not, this + /// method should have no observable side-effect on the lexed tokens. + bool isNextPPTokenLParen(); + private: /// Identifiers used for SEH handling in Borland. These are only /// allowed in particular circumstances @@ -2650,11 +2655,6 @@ class Preprocessor { void removeCachedMacroExpandedTokensOfLastLexer(); - /// Determine whether the next preprocessor token to be - /// lexed is a '('. If so, consume the token and return true, if not, this - /// method should have no observable side-effect on the lexed tokens. - bool isNextPPTokenLParen(); - /// After reading "MACRO(", this method is invoked to read all of the formal /// arguments specified for the macro invocation. Returns null on error. MacroArgs *ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI, diff --git a/clang/include/clang/Sema/CMakeLists.txt b/clang/include/clang/Sema/CMakeLists.txt index 0b0e31ece3195d..9077e22c2307cd 100644 --- a/clang/include/clang/Sema/CMakeLists.txt +++ b/clang/include/clang/Sema/CMakeLists.txt @@ -3,11 +3,6 @@ clang_tablegen(AttrTemplateInstantiate.inc -gen-clang-attr-template-instantiate SOURCE ../Basic/Attr.td TARGET ClangAttrTemplateInstantiate) -clang_tablegen(AttrParsedAttrList.inc -gen-clang-attr-parsed-attr-list - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ - SOURCE ../Basic/Attr.td - TARGET ClangAttrParsedAttrList) - clang_tablegen(AttrParsedAttrKinds.inc -gen-clang-attr-parsed-attr-kinds -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ SOURCE ../Basic/Attr.td diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 4e77df9ec444c7..3cbba8d3a34d70 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -11,6 +11,8 @@ /// //===----------------------------------------------------------------------===// +#include "clang/Basic/AttributeCommonInfo.h" +#include "clang/Basic/Attributes.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/DirectoryEntry.h" #include "clang/Basic/FileManager.h" @@ -101,7 +103,8 @@ SourceRange Preprocessor::DiscardUntilEndOfDirective(Token &Tmp) { enum MacroDiag { MD_NoWarn, //> Not a reserved identifier MD_KeywordDef, //> Macro hides keyword, enabled by default - MD_ReservedMacro //> #define of #undef reserved id, disabled by default + MD_ReservedMacro, //> #define of #undef reserved id, disabled by default + MD_ReservedAttributeIdentifier }; /// Enumerates possible %select values for the pp_err_elif_after_else and @@ -177,6 +180,20 @@ static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, return false; } +static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II) { + const LangOptions &Lang = PP.getLangOpts(); + if (Lang.CPlusPlus && + hasAttribute(AttributeCommonInfo::Syntax::AS_CXX11, /*Scope*/ nullptr, II, + PP.getTargetInfo(), Lang) > 0) { + AttributeCommonInfo::Kind AttrKind = AttributeCommonInfo::getParsedKind( + II, /*Scope*/ nullptr, AttributeCommonInfo::Syntax::AS_CXX11); + return !((AttrKind == AttributeCommonInfo::Kind::AT_Likely || + AttrKind == AttributeCommonInfo::Kind::AT_Unlikely) && + PP.isNextPPTokenLParen()); + } + return false; +} + static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) { const LangOptions &Lang = PP.getLangOpts(); StringRef Text = II->getName(); @@ -186,6 +203,8 @@ static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) { return MD_KeywordDef; if (Lang.CPlusPlus11 && (Text == "override" || Text == "final")) return MD_KeywordDef; + if (isReservedCXXAttributeName(PP, II)) + return MD_ReservedAttributeIdentifier; return MD_NoWarn; } @@ -194,6 +213,8 @@ static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II) { // Do not warn on keyword undef. It is generally harmless and widely used. if (isReservedInAllContexts(II->isReserved(Lang))) return MD_ReservedMacro; + if (isReservedCXXAttributeName(PP, II)) + return MD_ReservedAttributeIdentifier; return MD_NoWarn; } @@ -369,6 +390,9 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, } if (D == MD_ReservedMacro) Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id); + if (D == MD_ReservedAttributeIdentifier) + Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id) + << II->getName(); } // Okay, we got a good identifier. diff --git a/clang/test/Preprocessor/macro-reserved-attrs1.cpp b/clang/test/Preprocessor/macro-reserved-attrs1.cpp new file mode 100644 index 00000000000000..6a7554e1b83a67 --- /dev/null +++ b/clang/test/Preprocessor/macro-reserved-attrs1.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s + +#define noreturn 1 // expected-warning {{noreturn is a reserved attribute identifier}} +#undef noreturn // expected-warning {{noreturn is a reserved attribute identifier}} + +#define assume 1 // expected-warning {{assume is a reserved attribute identifier}} +#undef assume // expected-warning {{assume is a reserved attribute identifier}} + +#define carries_dependency 1 // expected-warning {{carries_dependency is a reserved attribute identifier}} +#undef carries_dependency // expected-warning {{carries_dependency is a reserved attribute identifier}} + +#define deprecated 1 // expected-warning {{deprecated is a reserved attribute identifier}} +#undef deprecated // expected-warning {{deprecated is a reserved attribute identifier}} + +#define fallthrough 1 // expected-warning {{fallthrough is a reserved attribute identifier}} +#undef fallthrough // expected-warning {{fallthrough is a reserved attribute identifier}} + +#define likely 1 // expected-warning {{likely is a reserved attribute identifier}} +#undef likely // expected-warning {{likely is a reserved attribute identifier}} + +#define no_unique_address 1 // expected-warning {{no_unique_address is a reserved attribute identifier}} +#undef no_unique_address // expected-warning {{no_unique_address is a reserved attribute identifier}} + +#define unlikely 1 // expected-warning {{unlikely is a reserved attribute identifier}} +#undef unlikely // expected-warning {{unlikely is a reserved attribute identifier}} + +#define maybe_unused 1 // expected-warning {{maybe_unused is a reserved attribute identifier}} +#undef maybe_unused // expected-warning {{maybe_unused is a reserved attribute identifier}} + +#define nodiscard 1 // expected-warning {{nodiscard is a reserved attribute identifier}} +#undef nodiscard // expected-warning {{nodiscard is a reserved attribute identifier}} + +#define likely() 1 // ok +#define unlikely() 1 // ok diff --git a/clang/test/Preprocessor/macro-reserved-attrs2.cpp b/clang/test/Preprocessor/macro-reserved-attrs2.cpp new file mode 100644 index 00000000000000..eddbe0cebb74ab --- /dev/null +++ b/clang/test/Preprocessor/macro-reserved-attrs2.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s + +#define noreturn // expected-warning {{noreturn is a reserved attribute identifier}} +#undef noreturn // expected-warning {{noreturn is a reserved attribute identifier}} + +#define assume // expected-warning {{assume is a reserved attribute identifier}} +#undef assume // expected-warning {{assume is a reserved attribute identifier}} + +#define carries_dependency // expected-warning {{carries_dependency is a reserved attribute identifier}} +#undef carries_dependency // expected-warning {{carries_dependency is a reserved attribute identifier}} + +#define deprecated // expected-warning {{deprecated is a reserved attribute identifier}} +#undef deprecated // expected-warning {{deprecated is a reserved attribute identifier}} + +#define fallthrough // expected-warning {{fallthrough is a reserved attribute identifier}} +#undef fallthrough // expected-warning {{fallthrough is a reserved attribute identifier}} + +#define likely // expected-warning {{likely is a reserved attribute identifier}} +#undef likely // expected-warning {{likely is a reserved attribute identifier}} + +#define no_unique_address // expected-warning {{no_unique_address is a reserved attribute identifier}} +#undef no_unique_address // expected-warning {{no_unique_address is a reserved attribute identifier}} + +#define unlikely // expected-warning {{unlikely is a reserved attribute identifier}} +#undef unlikely // expected-warning {{unlikely is a reserved attribute identifier}} + +#define maybe_unused // expected-warning {{maybe_unused is a reserved attribute identifier}} +#undef maybe_unused // expected-warning {{maybe_unused is a reserved attribute identifier}} + +#define nodiscard // expected-warning {{nodiscard is a reserved attribute identifier}} +#undef nodiscard // expected-warning {{nodiscard is a reserved attribute identifier}} + +#define likely() // ok +#define unlikely() // ok diff --git a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn index 84d569d3426544..b8360ff81c9d10 100644 --- a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn @@ -22,6 +22,7 @@ static_library("Basic") { public_deps = [ # public_dep because public header Version.h includes generated Version.inc. "//clang/include/clang/Basic:AttrList", + "//clang/include/clang/Basic:AttrParsedAttrList", "//clang/include/clang/Basic:AttrSubMatchRulesList", "//clang/include/clang/Basic:Builtins", "//clang/include/clang/Basic:BuiltinsBPF", @@ -39,10 +40,6 @@ static_library("Basic") { "//clang/include/clang/Basic:riscv_vector_builtins", "//clang/include/clang/Basic:version", - # public_dep because public header AttributeCommonInfo.h includes generated - # AttrParsedAttrList.inc. - "//clang/include/clang/Sema:AttrParsedAttrList", - # public_dep because public header OpenMPKinds.h includes generated # OMP.h.inc. "//llvm/include/llvm/Frontend/OpenMP:public_tablegen", diff --git a/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn index 83a10d5b18bc83..2aa70151c49266 100644 --- a/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn @@ -9,6 +9,7 @@ static_library("Sema") { configs += [ "//llvm/utils/gn/build:clang_code" ] deps = [ ":OpenCLBuiltins", + "//clang/include/clang/Basic:AttrParsedAttrList", "//clang/include/clang/Basic:arm_cde_builtin_aliases", "//clang/include/clang/Basic:arm_cde_builtin_sema", "//clang/include/clang/Basic:arm_mve_builtin_aliases", @@ -22,7 +23,6 @@ static_library("Sema") { "//clang/include/clang/Basic:riscv_vector_builtin_sema", "//clang/include/clang/Sema:AttrParsedAttrImpl", "//clang/include/clang/Sema:AttrParsedAttrKinds", - "//clang/include/clang/Sema:AttrParsedAttrList", "//clang/include/clang/Sema:AttrSpellingListIndex", "//clang/include/clang/Sema:AttrTemplateInstantiate", "//clang/lib/APINotes", diff --git a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel index 1d0ba8bd4d586d..7885d0b47a2ef8 100644 --- a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel @@ -529,6 +529,10 @@ gentbl( "-gen-clang-attr-list", "include/clang/Basic/AttrList.inc", ), + ( + "-gen-clang-attr-parsed-attr-list", + "include/clang/Basic/AttrParsedAttrList.inc", + ), ( "-gen-clang-attr-subject-match-rule-list", "include/clang/Basic/AttrSubMatchRulesList.inc", @@ -1096,10 +1100,6 @@ gentbl( "-gen-clang-attr-parsed-attr-kinds", "include/clang/Sema/AttrParsedAttrKinds.inc", ), - ( - "-gen-clang-attr-parsed-attr-list", - "include/clang/Sema/AttrParsedAttrList.inc", - ), ( "-gen-clang-attr-spelling-index", "include/clang/Sema/AttrSpellingListIndex.inc", @@ -1135,7 +1135,6 @@ cc_library( textual_hdrs = [ "include/clang/Sema/AttrParsedAttrImpl.inc", "include/clang/Sema/AttrParsedAttrKinds.inc", - "include/clang/Sema/AttrParsedAttrList.inc", "include/clang/Sema/AttrSpellingListIndex.inc", "include/clang/Sema/AttrTemplateInstantiate.inc", "lib/Sema/OpenCLBuiltins.inc", >From 26953b4e8eb53facb8c662bd76741ec0828e281e Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Thu, 26 Dec 2024 01:48:38 +0200 Subject: [PATCH 2/2] perform checks on reserved attribute names only if the std namespace is loaded --- .../include/clang/Basic/AttributeCommonInfo.h | 2 +- clang/include/clang/Basic/CMakeLists.txt | 5 --- .../include/clang/Basic/DiagnosticLexKinds.td | 2 -- .../clang/Basic/DiagnosticSemaKinds.td | 3 ++ clang/include/clang/Lex/Preprocessor.h | 10 +++--- clang/include/clang/Sema/CMakeLists.txt | 5 +++ clang/include/clang/Sema/Sema.h | 3 ++ clang/lib/Lex/PPDirectives.cpp | 24 ------------- clang/lib/Sema/Sema.cpp | 28 +++++++++++++++ clang/lib/Sema/SemaAttr.cpp | 23 ++++++++++++ .../macro-reserved-attrs1.cpp | 2 ++ .../macro-reserved-attrs2.cpp | 2 ++ clang/test/Sema/macro-reserved-attrs3.cpp | 35 +++++++++++++++++++ .../gn/secondary/clang/lib/Basic/BUILD.gn | 5 ++- .../gn/secondary/clang/lib/Sema/BUILD.gn | 2 +- .../llvm-project-overlay/clang/BUILD.bazel | 9 ++--- 16 files changed, 117 insertions(+), 43 deletions(-) rename clang/test/{Preprocessor => Sema}/macro-reserved-attrs1.cpp (99%) rename clang/test/{Preprocessor => Sema}/macro-reserved-attrs2.cpp (99%) create mode 100644 clang/test/Sema/macro-reserved-attrs3.cpp diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h b/clang/include/clang/Basic/AttributeCommonInfo.h index 4fee781fb9c5a1..11c64547721739 100644 --- a/clang/include/clang/Basic/AttributeCommonInfo.h +++ b/clang/include/clang/Basic/AttributeCommonInfo.h @@ -61,7 +61,7 @@ class AttributeCommonInfo { }; enum Kind { #define PARSED_ATTR(NAME) AT_##NAME, -#include "clang/Basic/AttrParsedAttrList.inc" +#include "clang/Sema/AttrParsedAttrList.inc" #undef PARSED_ATTR NoSemaHandlerAttribute, IgnoredAttribute, diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 708cae4f4306d7..76ac3367e23a66 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -31,11 +31,6 @@ clang_tablegen(AttrList.inc -gen-clang-attr-list SOURCE Attr.td TARGET ClangAttrList) -clang_tablegen(AttrParsedAttrList.inc -gen-clang-attr-parsed-attr-list - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ - SOURCE Attr.td - TARGET ClangAttrParsedAttrList) - clang_tablegen(AttrSubMatchRulesList.inc -gen-clang-attr-subject-match-rule-list -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ SOURCE Attr.td diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 0d1f6949ee5843..889370221f32f0 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -407,8 +407,6 @@ def warn_pp_macro_hides_keyword : Extension< def warn_pp_macro_is_reserved_id : Warning< "macro name is a reserved identifier">, DefaultIgnore, InGroup<ReservedIdAsMacro>; -def warn_pp_macro_is_reserved_attribute_id : Warning< - "%0 is a reserved attribute identifier">, InGroup<ReservedAttributeIdentifier>; def warn_pp_objc_macro_redef_ignored : Warning< "ignoring redefinition of Objective-C qualifier macro">, InGroup<DiagGroup<"objc-macro-redefinition">>; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index dfb90501ce72d7..7c96d818592d67 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3144,6 +3144,9 @@ def warn_auto_var_is_id : Warning< InGroup<DiagGroup<"auto-var-id">>; // Attributes +def warn_pp_macro_is_reserved_attribute_id : Warning< + "%0 is a reserved attribute identifier">, InGroup<ReservedAttributeIdentifier>; + def warn_attribute_ignored_no_calls_in_stmt: Warning< "%0 attribute is ignored because there exists no call expression inside the " "statement">, diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 3c2dc6d760951b..3312d4ed1d798d 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -2271,11 +2271,6 @@ class Preprocessor { } } - /// Determine whether the next preprocessor token to be - /// lexed is a '('. If so, consume the token and return true, if not, this - /// method should have no observable side-effect on the lexed tokens. - bool isNextPPTokenLParen(); - private: /// Identifiers used for SEH handling in Borland. These are only /// allowed in particular circumstances @@ -2653,6 +2648,11 @@ class Preprocessor { void removeCachedMacroExpandedTokensOfLastLexer(); + /// Determine whether the next preprocessor token to be + /// lexed is a '('. If so, consume the token and return true, if not, this + /// method should have no observable side-effect on the lexed tokens. + bool isNextPPTokenLParen(); + /// After reading "MACRO(", this method is invoked to read all of the formal /// arguments specified for the macro invocation. Returns null on error. MacroArgs *ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI, diff --git a/clang/include/clang/Sema/CMakeLists.txt b/clang/include/clang/Sema/CMakeLists.txt index 9077e22c2307cd..0b0e31ece3195d 100644 --- a/clang/include/clang/Sema/CMakeLists.txt +++ b/clang/include/clang/Sema/CMakeLists.txt @@ -3,6 +3,11 @@ clang_tablegen(AttrTemplateInstantiate.inc -gen-clang-attr-template-instantiate SOURCE ../Basic/Attr.td TARGET ClangAttrTemplateInstantiate) +clang_tablegen(AttrParsedAttrList.inc -gen-clang-attr-parsed-attr-list + -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + SOURCE ../Basic/Attr.td + TARGET ClangAttrParsedAttrList) + clang_tablegen(AttrParsedAttrKinds.inc -gen-clang-attr-parsed-attr-kinds -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ SOURCE ../Basic/Attr.td diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d6f3508a5243f3..30c569f97613c2 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1810,6 +1810,9 @@ class Sema final : public SemaBase { SourceLocation IncludeLoc); void DiagnoseUnterminatedPragmaAlignPack(); + void DiagnoseReservedAttributeName(IdentifierInfo *II, SourceLocation Loc, + bool IsFunctionLike); + /// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off]. void ActOnPragmaMSStruct(PragmaMSStructKind Kind); diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 4889bd47c199e4..e8d3f2a5ddc43a 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -11,8 +11,6 @@ /// //===----------------------------------------------------------------------===// -#include "clang/Basic/AttributeCommonInfo.h" -#include "clang/Basic/Attributes.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/DirectoryEntry.h" #include "clang/Basic/FileManager.h" @@ -100,7 +98,6 @@ enum MacroDiag { MD_NoWarn, //> Not a reserved identifier MD_KeywordDef, //> Macro hides keyword, enabled by default MD_ReservedMacro, //> #define of #undef reserved id, disabled by default - MD_ReservedAttributeIdentifier }; /// Enumerates possible %select values for the pp_err_elif_after_else and @@ -176,20 +173,6 @@ static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, return false; } -static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II) { - const LangOptions &Lang = PP.getLangOpts(); - if (Lang.CPlusPlus && - hasAttribute(AttributeCommonInfo::Syntax::AS_CXX11, /*Scope*/ nullptr, II, - PP.getTargetInfo(), Lang) > 0) { - AttributeCommonInfo::Kind AttrKind = AttributeCommonInfo::getParsedKind( - II, /*Scope*/ nullptr, AttributeCommonInfo::Syntax::AS_CXX11); - return !((AttrKind == AttributeCommonInfo::Kind::AT_Likely || - AttrKind == AttributeCommonInfo::Kind::AT_Unlikely) && - PP.isNextPPTokenLParen()); - } - return false; -} - static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) { const LangOptions &Lang = PP.getLangOpts(); StringRef Text = II->getName(); @@ -199,8 +182,6 @@ static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) { return MD_KeywordDef; if (Lang.CPlusPlus11 && (Text == "override" || Text == "final")) return MD_KeywordDef; - if (isReservedCXXAttributeName(PP, II)) - return MD_ReservedAttributeIdentifier; return MD_NoWarn; } @@ -209,8 +190,6 @@ static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II) { // Do not warn on keyword undef. It is generally harmless and widely used. if (isReservedInAllContexts(II->isReserved(Lang))) return MD_ReservedMacro; - if (isReservedCXXAttributeName(PP, II)) - return MD_ReservedAttributeIdentifier; return MD_NoWarn; } @@ -386,9 +365,6 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, } if (D == MD_ReservedMacro) Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id); - if (D == MD_ReservedAttributeIdentifier) - Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id) - << II->getName(); } // Okay, we got a good identifier. diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 942e7ece4283e3..bc7dfb717300c1 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -158,6 +158,22 @@ class SemaPPCallbacks : public PPCallbacks { llvm::SmallVector<SourceLocation, 8> IncludeStack; llvm::SmallVector<llvm::TimeTraceProfilerEntry *, 8> ProfilerStack; + void DiagnoseReservedAttributeName(const Token &MacroNameTok, + const MacroInfo *MI) { + IdentifierInfo *II = MacroNameTok.getIdentifierInfo(); + if (II == nullptr || MI == nullptr) + return; + + if (S) { + SourceManager &SM = S->getSourceManager(); + SourceLocation Loc = MacroNameTok.getLocation(); + if (SM.isInSystemHeader(Loc) || SM.getBufferName(Loc) == "<built-in>") + return; + + S->DiagnoseReservedAttributeName(II, Loc, MI->isFunctionLike()); + } + } + public: void set(Sema &S) { this->S = &S; } @@ -200,6 +216,18 @@ class SemaPPCallbacks : public PPCallbacks { break; } } + + void MacroDefined(const Token &MacroNameTok, + const MacroDirective *MD) override { + if (MD) { + DiagnoseReservedAttributeName(MacroNameTok, MD->getMacroInfo()); + } + } + + void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, + const MacroDirective *Undef) override { + DiagnoseReservedAttributeName(MacroNameTok, MD.getMacroInfo()); + } }; } // end namespace sema diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 9fbad7ed67ccbe..e1eb6f9d1f31b0 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -14,6 +14,7 @@ #include "clang/AST/ASTConsumer.h" #include "clang/AST/Attr.h" #include "clang/AST/Expr.h" +#include "clang/Basic/Attributes.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Lookup.h" @@ -564,6 +565,28 @@ void Sema::DiagnoseUnterminatedPragmaAlignPack() { } } +static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II, + bool IsFunctionLike) { + const LangOptions &Lang = PP.getLangOpts(); + if (hasAttribute(AttributeCommonInfo::Syntax::AS_CXX11, /*Scope*/ nullptr, II, + PP.getTargetInfo(), Lang) > 0) { + AttributeCommonInfo::Kind AttrKind = AttributeCommonInfo::getParsedKind( + II, /*Scope*/ nullptr, AttributeCommonInfo::Syntax::AS_CXX11); + return !((AttrKind == AttributeCommonInfo::Kind::AT_Likely || + AttrKind == AttributeCommonInfo::Kind::AT_Unlikely) && + IsFunctionLike); + } + return false; +} + +void Sema::DiagnoseReservedAttributeName(IdentifierInfo *II, SourceLocation Loc, + bool IsFunctionLike) { + if (getStdNamespace() && + isReservedCXXAttributeName(getPreprocessor(), II, IsFunctionLike)) { + Diag(Loc, diag::warn_pp_macro_is_reserved_attribute_id) << II->getName(); + } +} + void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) { MSStructPragmaOn = (Kind == PMSST_ON); } diff --git a/clang/test/Preprocessor/macro-reserved-attrs1.cpp b/clang/test/Sema/macro-reserved-attrs1.cpp similarity index 99% rename from clang/test/Preprocessor/macro-reserved-attrs1.cpp rename to clang/test/Sema/macro-reserved-attrs1.cpp index 6a7554e1b83a67..29a78c96c1aef2 100644 --- a/clang/test/Preprocessor/macro-reserved-attrs1.cpp +++ b/clang/test/Sema/macro-reserved-attrs1.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s +namespace std { } + #define noreturn 1 // expected-warning {{noreturn is a reserved attribute identifier}} #undef noreturn // expected-warning {{noreturn is a reserved attribute identifier}} diff --git a/clang/test/Preprocessor/macro-reserved-attrs2.cpp b/clang/test/Sema/macro-reserved-attrs2.cpp similarity index 99% rename from clang/test/Preprocessor/macro-reserved-attrs2.cpp rename to clang/test/Sema/macro-reserved-attrs2.cpp index eddbe0cebb74ab..3bc296ecd002c8 100644 --- a/clang/test/Preprocessor/macro-reserved-attrs2.cpp +++ b/clang/test/Sema/macro-reserved-attrs2.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s +namespace std { } + #define noreturn // expected-warning {{noreturn is a reserved attribute identifier}} #undef noreturn // expected-warning {{noreturn is a reserved attribute identifier}} diff --git a/clang/test/Sema/macro-reserved-attrs3.cpp b/clang/test/Sema/macro-reserved-attrs3.cpp new file mode 100644 index 00000000000000..3306139f075b4d --- /dev/null +++ b/clang/test/Sema/macro-reserved-attrs3.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -nostdinc++ -verify -pedantic %s +// expected-no-diagnostics + +#define noreturn +#undef noreturn + +#define assume +#undef assume + +#define carries_dependency +#undef carries_dependency + +#define deprecated +#undef deprecated + +#define fallthrough +#undef fallthrough + +#define likely +#undef likely + +#define no_unique_address +#undef no_unique_address + +#define unlikely +#undef unlikely + +#define maybe_unused +#undef maybe_unused + +#define nodiscard +#undef nodiscard + +#define likely() +#define unlikely() diff --git a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn index a7208b1bd4c1f8..31b4ba6304a231 100644 --- a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn @@ -22,7 +22,6 @@ static_library("Basic") { public_deps = [ # public_dep because public header Version.h includes generated Version.inc. "//clang/include/clang/Basic:AttrList", - "//clang/include/clang/Basic:AttrParsedAttrList", "//clang/include/clang/Basic:AttrSubMatchRulesList", "//clang/include/clang/Basic:Builtins", "//clang/include/clang/Basic:BuiltinsBPF", @@ -41,6 +40,10 @@ static_library("Basic") { "//clang/include/clang/Basic:riscv_vector_builtins", "//clang/include/clang/Basic:version", + # public_dep because public header AttributeCommonInfo.h includes generated + # AttrParsedAttrList.inc. + "//clang/include/clang/Sema:AttrParsedAttrList", + # public_dep because public header OpenMPKinds.h includes generated # OMP.h.inc. "//llvm/include/llvm/Frontend/OpenMP:public_tablegen", diff --git a/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn index d46fe4827b955d..bcd36779b85ef7 100644 --- a/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn @@ -9,7 +9,6 @@ static_library("Sema") { configs += [ "//llvm/utils/gn/build:clang_code" ] deps = [ ":OpenCLBuiltins", - "//clang/include/clang/Basic:AttrParsedAttrList", "//clang/include/clang/Basic:arm_cde_builtin_aliases", "//clang/include/clang/Basic:arm_cde_builtin_sema", "//clang/include/clang/Basic:arm_mve_builtin_aliases", @@ -23,6 +22,7 @@ static_library("Sema") { "//clang/include/clang/Basic:riscv_vector_builtin_sema", "//clang/include/clang/Sema:AttrParsedAttrImpl", "//clang/include/clang/Sema:AttrParsedAttrKinds", + "//clang/include/clang/Sema:AttrParsedAttrList", "//clang/include/clang/Sema:AttrSpellingListIndex", "//clang/include/clang/Sema:AttrTemplateInstantiate", "//clang/lib/APINotes", diff --git a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel index 5f991014e60d21..91e7e0113aa02e 100644 --- a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel @@ -535,10 +535,6 @@ gentbl( "-gen-clang-attr-list", "include/clang/Basic/AttrList.inc", ), - ( - "-gen-clang-attr-parsed-attr-list", - "include/clang/Basic/AttrParsedAttrList.inc", - ), ( "-gen-clang-attr-subject-match-rule-list", "include/clang/Basic/AttrSubMatchRulesList.inc", @@ -1111,6 +1107,10 @@ gentbl( "-gen-clang-attr-parsed-attr-kinds", "include/clang/Sema/AttrParsedAttrKinds.inc", ), + ( + "-gen-clang-attr-parsed-attr-list", + "include/clang/Sema/AttrParsedAttrList.inc", + ), ( "-gen-clang-attr-spelling-index", "include/clang/Sema/AttrSpellingListIndex.inc", @@ -1146,6 +1146,7 @@ cc_library( textual_hdrs = [ "include/clang/Sema/AttrParsedAttrImpl.inc", "include/clang/Sema/AttrParsedAttrKinds.inc", + "include/clang/Sema/AttrParsedAttrList.inc", "include/clang/Sema/AttrSpellingListIndex.inc", "include/clang/Sema/AttrTemplateInstantiate.inc", "lib/Sema/OpenCLBuiltins.inc", _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits