File tree Expand file tree Collapse file tree 4 files changed +30
-4
lines changed Expand file tree Collapse file tree 4 files changed +30
-4
lines changed Original file line number Diff line number Diff line change @@ -391,6 +391,7 @@ def warn_reserved_extern_symbol: Warning<
391
391
"identifier %0 is reserved because %select{"
392
392
"<ERROR>|" // ReservedIdentifierStatus::NotReserved
393
393
"it starts with '_' at global scope|"
394
+ "it starts with '_' and has C language linkage|"
394
395
"it starts with '__'|"
395
396
"it starts with '_' followed by a capital letter|"
396
397
"it contains '__'}1">,
Original file line number Diff line number Diff line change @@ -43,6 +43,7 @@ class SourceLocation;
43
43
enum class ReservedIdentifierStatus {
44
44
NotReserved = 0 ,
45
45
StartsWithUnderscoreAtGlobalScope,
46
+ StartsWithUnderscoreAndIsExternC,
46
47
StartsWithDoubleUnderscore,
47
48
StartsWithUnderscoreFollowedByCapitalLetter,
48
49
ContainsDoubleUnderscore,
@@ -60,7 +61,8 @@ inline bool isReservedAtGlobalScope(ReservedIdentifierStatus Status) {
60
61
// / example.
61
62
inline bool isReservedInAllContexts (ReservedIdentifierStatus Status) {
62
63
return Status != ReservedIdentifierStatus::NotReserved &&
63
- Status != ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope;
64
+ Status != ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope &&
65
+ Status != ReservedIdentifierStatus::StartsWithUnderscoreAndIsExternC;
64
66
}
65
67
66
68
// / A simple pair of identifier info and location.
Original file line number Diff line number Diff line change @@ -1089,12 +1089,28 @@ NamedDecl::isReserved(const LangOptions &LangOpts) const {
1089
1089
1090
1090
ReservedIdentifierStatus Status = II->isReserved (LangOpts);
1091
1091
if (isReservedAtGlobalScope (Status) && !isReservedInAllContexts (Status)) {
1092
- // Check if we're at TU level or not.
1092
+ // This name is only reserved at global scope. Check if this declaration
1093
+ // conflicts with a global scope declaration.
1093
1094
if (isa<ParmVarDecl>(this ) || isTemplateParameter ())
1094
1095
return ReservedIdentifierStatus::NotReserved;
1096
+
1097
+ // C++ [dcl.link]/7:
1098
+ // Two declarations [conflict] if [...] one declares a function or
1099
+ // variable with C language linkage, and the other declares [...] a
1100
+ // variable that belongs to the global scope.
1101
+ //
1102
+ // Therefore names that are reserved at global scope are also reserved as
1103
+ // names of variables and functions with C language linkage.
1095
1104
const DeclContext *DC = getDeclContext ()->getRedeclContext ();
1096
- if (!DC->isTranslationUnit ())
1097
- return ReservedIdentifierStatus::NotReserved;
1105
+ if (DC->isTranslationUnit ())
1106
+ return Status;
1107
+ if (auto *VD = dyn_cast<VarDecl>(this ))
1108
+ if (VD->isExternC ())
1109
+ return ReservedIdentifierStatus::StartsWithUnderscoreAndIsExternC;
1110
+ if (auto *FD = dyn_cast<FunctionDecl>(this ))
1111
+ if (FD->isExternC ())
1112
+ return ReservedIdentifierStatus::StartsWithUnderscoreAndIsExternC;
1113
+ return ReservedIdentifierStatus::NotReserved;
1098
1114
}
1099
1115
1100
1116
return Status;
Original file line number Diff line number Diff line change @@ -105,3 +105,10 @@ struct Any {
105
105
#define _Reserved // expected-warning {{macro name is a reserved identifier}}
106
106
#undef _not_reserved
107
107
#undef _Reserved // expected-warning {{macro name is a reserved identifier}}
108
+
109
+ namespace N {
110
+ int _namespace_a;
111
+ extern " C" int _namespace_b; // expected-warning {{identifier '_namespace_b' is reserved because it starts with '_' and has C language linkage}}
112
+ void _namespace_c ();
113
+ extern " C" void _namespace_d (); // expected-warning {{identifier '_namespace_d' is reserved because it starts with '_' and has C language linkage}}
114
+ }
You can’t perform that action at this time.
0 commit comments