[clang] [Clang][Sema] Diagnose function/variable templates that shadow their own template parameters (PR #78274)
Krystian Stasiowski via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 16 10:40:07 PST 2024
https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/78274
>From 90d66e29f3550d50bd114d68fc8b12156e26de18 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 16 Jan 2024 08:05:33 -0500
Subject: [PATCH] [Clang][Sema] Diagnose function/variable templates that
shadow their own template parameters
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/Sema/SemaDecl.cpp | 12 +++++------
.../test/CXX/temp/temp.res/temp.local/p6.cpp | 20 ++++++++++++++++---
3 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ea57769a4a5795d..030e4ebce177638 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -555,6 +555,7 @@ Improvements to Clang's diagnostics
- Clang now diagnoses unexpanded packs within the template argument lists of function template specializations.
- Clang now diagnoses attempts to bind a bitfield to an NTTP of a reference type as erroneous
converted constant expression and not as a reference to subobject.
+- Clang now diagnoses function/variable templates that shadow their own template parameters, e.g. ``template<class T> void T();``.
Improvements to Clang's time-trace
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 722e2ac9e4ff8da..6345e1d3208b990 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6371,12 +6371,6 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
} else if (DiagnoseUnexpandedParameterPack(NameInfo, UPPC_DeclarationType))
return nullptr;
- // The scope passed in may not be a decl scope. Zip up the scope tree until
- // we find one that is.
- while ((S->getFlags() & Scope::DeclScope) == 0 ||
- (S->getFlags() & Scope::TemplateParamScope) != 0)
- S = S->getParent();
-
DeclContext *DC = CurContext;
if (D.getCXXScopeSpec().isInvalid())
D.setInvalidType();
@@ -6529,6 +6523,12 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
if (getLangOpts().CPlusPlus)
CheckExtraCXXDefaultArguments(D);
+ // The scope passed in may not be a decl scope. Zip up the scope tree until
+ // we find one that is.
+ while ((S->getFlags() & Scope::DeclScope) == 0 ||
+ (S->getFlags() & Scope::TemplateParamScope) != 0)
+ S = S->getParent();
+
NamedDecl *New;
bool AddToScope = true;
diff --git a/clang/test/CXX/temp/temp.res/temp.local/p6.cpp b/clang/test/CXX/temp/temp.res/temp.local/p6.cpp
index e2aa0ff344291d2..0702966e5685480 100644
--- a/clang/test/CXX/temp/temp.res/temp.local/p6.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.local/p6.cpp
@@ -127,16 +127,30 @@ template<int T> struct Z { // expected-note 16{{declared here}}
template<typename T> // expected-note {{declared here}}
void f(int T) {} // expected-error {{declaration of 'T' shadows template parameter}}
-// FIXME: These are ill-formed: a template-parameter shall not have the same name as the template name.
namespace A {
template<typename T> struct T {}; // expected-error{{declaration of 'T' shadows template parameter}}
// expected-note at -1{{template parameter is declared here}}
+ template<typename T> struct U {
+ template<typename V> struct V {}; // expected-error{{declaration of 'V' shadows template parameter}}
+ // expected-note at -1{{template parameter is declared here}}
+ };
}
namespace B {
- template<typename T> void T() {}
+ template<typename T> void T() {} // expected-error{{declaration of 'T' shadows template parameter}}
+ // expected-note at -1{{template parameter is declared here}}
+
+ template<typename T> struct U {
+ template<typename V> void V(); // expected-error{{declaration of 'V' shadows template parameter}}
+ // expected-note at -1{{template parameter is declared here}}
+ };
}
namespace C {
- template<typename T> int T;
+ template<typename T> int T; // expected-error{{declaration of 'T' shadows template parameter}}
+ // expected-note at -1{{template parameter is declared here}}
+ template<typename T> struct U {
+ template<typename V> static int V; // expected-error{{declaration of 'V' shadows template parameter}}
+ // expected-note at -1{{template parameter is declared here}}
+ };
}
namespace PR28023 {
More information about the cfe-commits
mailing list