Skip to content

Commit 4ac6eb8

Browse files
committed
[Clang][Sema] Diagnose function/variable templates that shadow their own template parameters
1 parent bbf2304 commit 4ac6eb8

File tree

3 files changed

+24
-9
lines changed

3 files changed

+24
-9
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ Improvements to Clang's diagnostics
568568
- Clang now diagnoses the requirement that non-template friend declarations with requires clauses
569569
and template friend declarations with a constraint that depends on a template parameter from an
570570
enclosing template must be a definition.
571+
- Clang now diagnoses function/variable templates that shadow their own template parameters, e.g. ``template<class T> void T();``.
571572

572573

573574
Improvements to Clang's time-trace

clang/lib/Sema/SemaDecl.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6377,12 +6377,6 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
63776377
} else if (DiagnoseUnexpandedParameterPack(NameInfo, UPPC_DeclarationType))
63786378
return nullptr;
63796379

6380-
// The scope passed in may not be a decl scope. Zip up the scope tree until
6381-
// we find one that is.
6382-
while ((S->getFlags() & Scope::DeclScope) == 0 ||
6383-
(S->getFlags() & Scope::TemplateParamScope) != 0)
6384-
S = S->getParent();
6385-
63866380
DeclContext *DC = CurContext;
63876381
if (D.getCXXScopeSpec().isInvalid())
63886382
D.setInvalidType();
@@ -6535,6 +6529,12 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
65356529
if (getLangOpts().CPlusPlus)
65366530
CheckExtraCXXDefaultArguments(D);
65376531

6532+
// The scope passed in may not be a decl scope. Zip up the scope tree until
6533+
// we find one that is.
6534+
while ((S->getFlags() & Scope::DeclScope) == 0 ||
6535+
(S->getFlags() & Scope::TemplateParamScope) != 0)
6536+
S = S->getParent();
6537+
65386538
NamedDecl *New;
65396539

65406540
bool AddToScope = true;

clang/test/CXX/temp/temp.res/temp.local/p6.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,16 +127,30 @@ template<int T> struct Z { // expected-note 16{{declared here}}
127127
template<typename T> // expected-note {{declared here}}
128128
void f(int T) {} // expected-error {{declaration of 'T' shadows template parameter}}
129129

130-
// FIXME: These are ill-formed: a template-parameter shall not have the same name as the template name.
131130
namespace A {
132131
template<typename T> struct T {}; // expected-error{{declaration of 'T' shadows template parameter}}
133132
// expected-note@-1{{template parameter is declared here}}
133+
template<typename T> struct U {
134+
template<typename V> struct V {}; // expected-error{{declaration of 'V' shadows template parameter}}
135+
// expected-note@-1{{template parameter is declared here}}
136+
};
134137
}
135138
namespace B {
136-
template<typename T> void T() {}
139+
template<typename T> void T() {} // expected-error{{declaration of 'T' shadows template parameter}}
140+
// expected-note@-1{{template parameter is declared here}}
141+
142+
template<typename T> struct U {
143+
template<typename V> void V(); // expected-error{{declaration of 'V' shadows template parameter}}
144+
// expected-note@-1{{template parameter is declared here}}
145+
};
137146
}
138147
namespace C {
139-
template<typename T> int T;
148+
template<typename T> int T; // expected-error{{declaration of 'T' shadows template parameter}}
149+
// expected-note@-1{{template parameter is declared here}}
150+
template<typename T> struct U {
151+
template<typename V> static int V; // expected-error{{declaration of 'V' shadows template parameter}}
152+
// expected-note@-1{{template parameter is declared here}}
153+
};
140154
}
141155

142156
namespace PR28023 {

0 commit comments

Comments
 (0)