Skip to content

Commit d4b07c7

Browse files
committed
[Clang] restrict use of attribute names reserved by the C++ standard
1 parent 6f8d278 commit d4b07c7

File tree

13 files changed

+115
-22
lines changed

13 files changed

+115
-22
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ Improvements to Clang's diagnostics
298298

299299
- Clang now warns for u8 character literals used in C23 with ``-Wpre-c23-compat`` instead of ``-Wpre-c++17-compat``.
300300

301+
- Clang now diagnoses the use of attribute names reserved by the C++ standard. (#GH92196).
302+
301303
Improvements to Clang's time-trace
302304
----------------------------------
303305

clang/include/clang/Basic/AttributeCommonInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class AttributeCommonInfo {
6161
};
6262
enum Kind {
6363
#define PARSED_ATTR(NAME) AT_##NAME,
64-
#include "clang/Sema/AttrParsedAttrList.inc"
64+
#include "clang/Basic/AttrParsedAttrList.inc"
6565
#undef PARSED_ATTR
6666
NoSemaHandlerAttribute,
6767
IgnoredAttribute,

clang/include/clang/Basic/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ clang_tablegen(AttrList.inc -gen-clang-attr-list
3131
SOURCE Attr.td
3232
TARGET ClangAttrList)
3333

34+
clang_tablegen(AttrParsedAttrList.inc -gen-clang-attr-parsed-attr-list
35+
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
36+
SOURCE Attr.td
37+
TARGET ClangAttrParsedAttrList)
38+
3439
clang_tablegen(AttrSubMatchRulesList.inc -gen-clang-attr-subject-match-rule-list
3540
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
3641
SOURCE Attr.td

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ def AmbiguousMacro : DiagGroup<"ambiguous-macro">;
751751
def KeywordAsMacro : DiagGroup<"keyword-macro">;
752752
def ReservedIdAsMacro : DiagGroup<"reserved-macro-identifier">;
753753
def ReservedIdAsMacroAlias : DiagGroup<"reserved-id-macro", [ReservedIdAsMacro]>;
754+
def ReservedAttributeIdentifier : DiagGroup<"reserved-attribute-identifier">;
754755
def RestrictExpansionMacro : DiagGroup<"restrict-expansion">;
755756
def FinalMacro : DiagGroup<"final-macro">;
756757

clang/include/clang/Basic/DiagnosticLexKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,8 @@ def warn_pp_macro_hides_keyword : Extension<
407407
def warn_pp_macro_is_reserved_id : Warning<
408408
"macro name is a reserved identifier">, DefaultIgnore,
409409
InGroup<ReservedIdAsMacro>;
410+
def warn_pp_macro_is_reserved_attribute_id : Warning<
411+
"%0 is a reserved attribute identifier">, InGroup<ReservedAttributeIdentifier>;
410412
def warn_pp_objc_macro_redef_ignored : Warning<
411413
"ignoring redefinition of Objective-C qualifier macro">,
412414
InGroup<DiagGroup<"objc-macro-redefinition">>;

clang/include/clang/Lex/Preprocessor.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2286,6 +2286,11 @@ class Preprocessor {
22862286
}
22872287
}
22882288

2289+
/// Determine whether the next preprocessor token to be
2290+
/// lexed is a '('. If so, consume the token and return true, if not, this
2291+
/// method should have no observable side-effect on the lexed tokens.
2292+
bool isNextPPTokenLParen();
2293+
22892294
private:
22902295
/// Identifiers used for SEH handling in Borland. These are only
22912296
/// allowed in particular circumstances
@@ -2650,11 +2655,6 @@ class Preprocessor {
26502655

26512656
void removeCachedMacroExpandedTokensOfLastLexer();
26522657

2653-
/// Determine whether the next preprocessor token to be
2654-
/// lexed is a '('. If so, consume the token and return true, if not, this
2655-
/// method should have no observable side-effect on the lexed tokens.
2656-
bool isNextPPTokenLParen();
2657-
26582658
/// After reading "MACRO(", this method is invoked to read all of the formal
26592659
/// arguments specified for the macro invocation. Returns null on error.
26602660
MacroArgs *ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI,

clang/include/clang/Sema/CMakeLists.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@ clang_tablegen(AttrTemplateInstantiate.inc -gen-clang-attr-template-instantiate
33
SOURCE ../Basic/Attr.td
44
TARGET ClangAttrTemplateInstantiate)
55

6-
clang_tablegen(AttrParsedAttrList.inc -gen-clang-attr-parsed-attr-list
7-
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
8-
SOURCE ../Basic/Attr.td
9-
TARGET ClangAttrParsedAttrList)
10-
116
clang_tablegen(AttrParsedAttrKinds.inc -gen-clang-attr-parsed-attr-kinds
127
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
138
SOURCE ../Basic/Attr.td

clang/lib/Lex/PPDirectives.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
///
1212
//===----------------------------------------------------------------------===//
1313

14+
#include "clang/Basic/AttributeCommonInfo.h"
15+
#include "clang/Basic/Attributes.h"
1416
#include "clang/Basic/CharInfo.h"
1517
#include "clang/Basic/DirectoryEntry.h"
1618
#include "clang/Basic/FileManager.h"
@@ -101,7 +103,8 @@ SourceRange Preprocessor::DiscardUntilEndOfDirective(Token &Tmp) {
101103
enum MacroDiag {
102104
MD_NoWarn, //> Not a reserved identifier
103105
MD_KeywordDef, //> Macro hides keyword, enabled by default
104-
MD_ReservedMacro //> #define of #undef reserved id, disabled by default
106+
MD_ReservedMacro, //> #define of #undef reserved id, disabled by default
107+
MD_ReservedAttributeIdentifier
105108
};
106109

107110
/// Enumerates possible %select values for the pp_err_elif_after_else and
@@ -177,6 +180,20 @@ static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr,
177180
return false;
178181
}
179182

183+
static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II) {
184+
const LangOptions &Lang = PP.getLangOpts();
185+
if (Lang.CPlusPlus &&
186+
hasAttribute(AttributeCommonInfo::Syntax::AS_CXX11, /*Scope*/ nullptr, II,
187+
PP.getTargetInfo(), Lang) > 0) {
188+
AttributeCommonInfo::Kind AttrKind = AttributeCommonInfo::getParsedKind(
189+
II, /*Scope*/ nullptr, AttributeCommonInfo::Syntax::AS_CXX11);
190+
return !((AttrKind == AttributeCommonInfo::Kind::AT_Likely ||
191+
AttrKind == AttributeCommonInfo::Kind::AT_Unlikely) &&
192+
PP.isNextPPTokenLParen());
193+
}
194+
return false;
195+
}
196+
180197
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) {
181198
const LangOptions &Lang = PP.getLangOpts();
182199
StringRef Text = II->getName();
@@ -186,6 +203,8 @@ static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) {
186203
return MD_KeywordDef;
187204
if (Lang.CPlusPlus11 && (Text == "override" || Text == "final"))
188205
return MD_KeywordDef;
206+
if (isReservedCXXAttributeName(PP, II))
207+
return MD_ReservedAttributeIdentifier;
189208
return MD_NoWarn;
190209
}
191210

@@ -194,6 +213,8 @@ static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II) {
194213
// Do not warn on keyword undef. It is generally harmless and widely used.
195214
if (isReservedInAllContexts(II->isReserved(Lang)))
196215
return MD_ReservedMacro;
216+
if (isReservedCXXAttributeName(PP, II))
217+
return MD_ReservedAttributeIdentifier;
197218
return MD_NoWarn;
198219
}
199220

@@ -369,6 +390,9 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
369390
}
370391
if (D == MD_ReservedMacro)
371392
Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
393+
if (D == MD_ReservedAttributeIdentifier)
394+
Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id)
395+
<< II->getName();
372396
}
373397

374398
// Okay, we got a good identifier.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s
2+
3+
#define noreturn 1 // expected-warning {{noreturn is a reserved attribute identifier}}
4+
#undef noreturn // expected-warning {{noreturn is a reserved attribute identifier}}
5+
6+
#define assume 1 // expected-warning {{assume is a reserved attribute identifier}}
7+
#undef assume // expected-warning {{assume is a reserved attribute identifier}}
8+
9+
#define carries_dependency 1 // expected-warning {{carries_dependency is a reserved attribute identifier}}
10+
#undef carries_dependency // expected-warning {{carries_dependency is a reserved attribute identifier}}
11+
12+
#define deprecated 1 // expected-warning {{deprecated is a reserved attribute identifier}}
13+
#undef deprecated // expected-warning {{deprecated is a reserved attribute identifier}}
14+
15+
#define fallthrough 1 // expected-warning {{fallthrough is a reserved attribute identifier}}
16+
#undef fallthrough // expected-warning {{fallthrough is a reserved attribute identifier}}
17+
18+
#define likely 1 // expected-warning {{likely is a reserved attribute identifier}}
19+
#undef likely // expected-warning {{likely is a reserved attribute identifier}}
20+
21+
#define no_unique_address 1 // expected-warning {{no_unique_address is a reserved attribute identifier}}
22+
#undef no_unique_address // expected-warning {{no_unique_address is a reserved attribute identifier}}
23+
24+
#define unlikely 1 // expected-warning {{unlikely is a reserved attribute identifier}}
25+
#undef unlikely // expected-warning {{unlikely is a reserved attribute identifier}}
26+
27+
#define maybe_unused 1 // expected-warning {{maybe_unused is a reserved attribute identifier}}
28+
#undef maybe_unused // expected-warning {{maybe_unused is a reserved attribute identifier}}
29+
30+
#define nodiscard 1 // expected-warning {{nodiscard is a reserved attribute identifier}}
31+
#undef nodiscard // expected-warning {{nodiscard is a reserved attribute identifier}}
32+
33+
#define likely() 1 // ok
34+
#define unlikely() 1 // ok
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s
2+
3+
#define noreturn // expected-warning {{noreturn is a reserved attribute identifier}}
4+
#undef noreturn // expected-warning {{noreturn is a reserved attribute identifier}}
5+
6+
#define assume // expected-warning {{assume is a reserved attribute identifier}}
7+
#undef assume // expected-warning {{assume is a reserved attribute identifier}}
8+
9+
#define carries_dependency // expected-warning {{carries_dependency is a reserved attribute identifier}}
10+
#undef carries_dependency // expected-warning {{carries_dependency is a reserved attribute identifier}}
11+
12+
#define deprecated // expected-warning {{deprecated is a reserved attribute identifier}}
13+
#undef deprecated // expected-warning {{deprecated is a reserved attribute identifier}}
14+
15+
#define fallthrough // expected-warning {{fallthrough is a reserved attribute identifier}}
16+
#undef fallthrough // expected-warning {{fallthrough is a reserved attribute identifier}}
17+
18+
#define likely // expected-warning {{likely is a reserved attribute identifier}}
19+
#undef likely // expected-warning {{likely is a reserved attribute identifier}}
20+
21+
#define no_unique_address // expected-warning {{no_unique_address is a reserved attribute identifier}}
22+
#undef no_unique_address // expected-warning {{no_unique_address is a reserved attribute identifier}}
23+
24+
#define unlikely // expected-warning {{unlikely is a reserved attribute identifier}}
25+
#undef unlikely // expected-warning {{unlikely is a reserved attribute identifier}}
26+
27+
#define maybe_unused // expected-warning {{maybe_unused is a reserved attribute identifier}}
28+
#undef maybe_unused // expected-warning {{maybe_unused is a reserved attribute identifier}}
29+
30+
#define nodiscard // expected-warning {{nodiscard is a reserved attribute identifier}}
31+
#undef nodiscard // expected-warning {{nodiscard is a reserved attribute identifier}}
32+
33+
#define likely() // ok
34+
#define unlikely() // ok

llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ static_library("Basic") {
2222
public_deps = [
2323
# public_dep because public header Version.h includes generated Version.inc.
2424
"//clang/include/clang/Basic:AttrList",
25+
"//clang/include/clang/Basic:AttrParsedAttrList",
2526
"//clang/include/clang/Basic:AttrSubMatchRulesList",
2627
"//clang/include/clang/Basic:Builtins",
2728
"//clang/include/clang/Basic:BuiltinsBPF",
@@ -39,10 +40,6 @@ static_library("Basic") {
3940
"//clang/include/clang/Basic:riscv_vector_builtins",
4041
"//clang/include/clang/Basic:version",
4142

42-
# public_dep because public header AttributeCommonInfo.h includes generated
43-
# AttrParsedAttrList.inc.
44-
"//clang/include/clang/Sema:AttrParsedAttrList",
45-
4643
# public_dep because public header OpenMPKinds.h includes generated
4744
# OMP.h.inc.
4845
"//llvm/include/llvm/Frontend/OpenMP:public_tablegen",

llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ static_library("Sema") {
99
configs += [ "//llvm/utils/gn/build:clang_code" ]
1010
deps = [
1111
":OpenCLBuiltins",
12+
"//clang/include/clang/Basic:AttrParsedAttrList",
1213
"//clang/include/clang/Basic:arm_cde_builtin_aliases",
1314
"//clang/include/clang/Basic:arm_cde_builtin_sema",
1415
"//clang/include/clang/Basic:arm_mve_builtin_aliases",
@@ -22,7 +23,6 @@ static_library("Sema") {
2223
"//clang/include/clang/Basic:riscv_vector_builtin_sema",
2324
"//clang/include/clang/Sema:AttrParsedAttrImpl",
2425
"//clang/include/clang/Sema:AttrParsedAttrKinds",
25-
"//clang/include/clang/Sema:AttrParsedAttrList",
2626
"//clang/include/clang/Sema:AttrSpellingListIndex",
2727
"//clang/include/clang/Sema:AttrTemplateInstantiate",
2828
"//clang/lib/APINotes",

utils/bazel/llvm-project-overlay/clang/BUILD.bazel

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,10 @@ gentbl(
529529
"-gen-clang-attr-list",
530530
"include/clang/Basic/AttrList.inc",
531531
),
532+
(
533+
"-gen-clang-attr-parsed-attr-list",
534+
"include/clang/Basic/AttrParsedAttrList.inc",
535+
),
532536
(
533537
"-gen-clang-attr-subject-match-rule-list",
534538
"include/clang/Basic/AttrSubMatchRulesList.inc",
@@ -1096,10 +1100,6 @@ gentbl(
10961100
"-gen-clang-attr-parsed-attr-kinds",
10971101
"include/clang/Sema/AttrParsedAttrKinds.inc",
10981102
),
1099-
(
1100-
"-gen-clang-attr-parsed-attr-list",
1101-
"include/clang/Sema/AttrParsedAttrList.inc",
1102-
),
11031103
(
11041104
"-gen-clang-attr-spelling-index",
11051105
"include/clang/Sema/AttrSpellingListIndex.inc",
@@ -1135,7 +1135,6 @@ cc_library(
11351135
textual_hdrs = [
11361136
"include/clang/Sema/AttrParsedAttrImpl.inc",
11371137
"include/clang/Sema/AttrParsedAttrKinds.inc",
1138-
"include/clang/Sema/AttrParsedAttrList.inc",
11391138
"include/clang/Sema/AttrSpellingListIndex.inc",
11401139
"include/clang/Sema/AttrTemplateInstantiate.inc",
11411140
"lib/Sema/OpenCLBuiltins.inc",

0 commit comments

Comments
 (0)