[clang] [llvm] [Clang] restrict use of attribute names reserved by the C++ standard (PR #106036)
Oleksandr T. via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 26 03:36:02 PST 2024
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.tarasiuk at outlook.com>
Date: Tue, 10 Sep 2024 02:35:43 +0300
Subject: [PATCH 1/4] [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.tarasiuk at outlook.com>
Date: Thu, 26 Dec 2024 01:48:38 +0200
Subject: [PATCH 2/4] 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",
>From eb647e2f7eaf99c90073d884ebf02a9336b50436 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Thu, 26 Dec 2024 01:53:00 +0200
Subject: [PATCH 3/4] update releaseNotes
---
clang/docs/ReleaseNotes.rst | 74 ++++++++++++++++++++++++++++++++++++-
1 file changed, 73 insertions(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6d654cd975ed4e..9e63742ab16911 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -662,7 +662,79 @@ Improvements to Clang's diagnostics
- Clang now omits shadowing warnings for parameter names in explicit object member functions (#GH95707).
-- Clang now diagnoses the use of attribute names reserved by the C++ standard. (#GH92196).
+- Improved error recovery for function call arguments with trailing commas (#GH100921).
+
+- For an rvalue reference bound to a temporary struct with an integer member, Clang will detect constant integer overflow
+ in the initializer for the integer member (#GH46755).
+
+- Fixed a false negative ``-Wunused-private-field`` diagnostic when a defaulted comparison operator is defined out of class (#GH116961).
+
+- Clang now diagnoses dangling references for C++20's parenthesized aggregate initialization (#101957).
+
+- Fixed a bug where Clang would not emit ``-Wunused-private-field`` warnings when an unrelated class
+ defined a defaulted comparison operator (#GH116270).
+
+ .. code-block:: c++
+
+ class A {
+ private:
+ int a; // warning: private field 'a' is not used, no diagnostic previously
+ };
+
+ class C {
+ bool operator==(const C&) = default;
+ };
+
+- Clang now emits `-Wdangling-capture` diangostic when a STL container captures a dangling reference.
+
+ .. code-block:: c++
+
+ void test() {
+ std::vector<std::string_view> views;
+ views.push_back(std::string("123")); // warning
+ }
+
+- Clang now emits a ``-Wtautological-compare`` diagnostic when a check for
+ pointer addition overflow is always true or false, because overflow would
+ be undefined behavior.
+
+ .. code-block:: c++
+
+ bool incorrect_overflow_check(const char *ptr, size_t index) {
+ return ptr + index < ptr; // warning
+ }
+
+- Fix -Wdangling false positives on conditional operators (#120206).
+
+- Fixed a bug where Clang hung on an unsupported optional scope specifier ``::`` when parsing
+ Objective-C. Clang now emits a diagnostic message instead of hanging.
+
+- The :doc:`ThreadSafetyAnalysis` now supports passing scoped capabilities into functions:
+ an attribute on the scoped capability parameter indicates both the expected associated capabilities and,
+ like in the case of attributes on the function declaration itself, their state before and after the call.
+
+ .. code-block:: c++
+
+ #include "mutex.h"
+
+ Mutex mu1, mu2;
+ int a GUARDED_BY(mu1);
+
+ void require(MutexLocker& scope REQUIRES(mu1)) {
+ scope.Unlock();
+ a = 0; // Warning! Requires mu1.
+ scope.Lock();
+ }
+
+ void testParameter() {
+ MutexLocker scope(&mu1), scope2(&mu2);
+ require(scope2); // Warning! Mutex managed by 'scope2' is 'mu2' instead of 'mu1'
+ require(scope); // OK.
+ scope.Unlock();
+ require(scope); // Warning! Requires mu1.
+ }
+
+- Clang now diagnoses the use of attribute names reserved by the C++ standard (#GH92196).
Improvements to Clang's time-trace
----------------------------------
>From 1962fcdaf13ddfc135d01900865b18a096408495 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Thu, 26 Dec 2024 13:35:42 +0200
Subject: [PATCH 4/4] cleanup
---
clang/lib/Lex/PPDirectives.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index e8d3f2a5ddc43a..a23ad40884f249 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -97,7 +97,7 @@ 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
};
/// Enumerates possible %select values for the pp_err_elif_after_else and
More information about the llvm-commits
mailing list