aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2019-09-12 18:26:34 +0000
committerReid Kleckner <rnk@google.com>2019-09-12 18:26:34 +0000
commitb6a8152b8bf7dc7b56e2953575037281af3d9133 (patch)
tree0bcc09b3be864b224feb5603be3aa22d9a63ad96
parent18f5204db4a9d5df3cb89833de4805a78f5034ee (diff)
downloadllvm-b6a8152b8bf7dc7b56e2953575037281af3d9133.zip
llvm-b6a8152b8bf7dc7b56e2953575037281af3d9133.tar.gz
llvm-b6a8152b8bf7dc7b56e2953575037281af3d9133.tar.bz2
[MS] Warn when shadowing template parameters under -fms-compatibility
Summary: C++ does not allow shadowing template parameters, but previously we allowed it under -fms-extensions. Now this behavior is controlled by -fms-compatibility, and we emit a -Wmicrosoft-template warning when it happens. Fixes PR43265 Reviewers: thakis, hans Subscribers: amccarth, rsmith, STL_MSFT, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D67463 llvm-svn: 371753
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp11
-rw-r--r--clang/test/Parser/DelayedTemplateParsing.cpp16
-rw-r--r--clang/test/SemaCXX/MicrosoftCompatibility.cpp18
4 files changed, 25 insertions, 22 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 2259695..46af145 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4000,6 +4000,8 @@ def err_ovl_no_viable_literal_operator : Error<
// C++ Template Declarations
def err_template_param_shadow : Error<
"declaration of %0 shadows template parameter">;
+def ext_template_param_shadow : ExtWarn<
+ err_template_param_shadow.Text>, InGroup<MicrosoftTemplate>;
def note_template_param_here : Note<"template parameter is declared here">;
def warn_template_export_unsupported : Warning<
"exported templates are unsupported">;
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 001e433..91466fa 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -849,15 +849,14 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
void Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
assert(PrevDecl->isTemplateParameter() && "Not a template parameter");
- // Microsoft Visual C++ permits template parameters to be shadowed.
- if (getLangOpts().MicrosoftExt)
- return;
-
// C++ [temp.local]p4:
// A template-parameter shall not be redeclared within its
// scope (including nested scopes).
- Diag(Loc, diag::err_template_param_shadow)
- << cast<NamedDecl>(PrevDecl)->getDeclName();
+ //
+ // Make this a warning when MSVC compatibility is requested.
+ unsigned DiagId = getLangOpts().MSVCCompat ? diag::ext_template_param_shadow
+ : diag::err_template_param_shadow;
+ Diag(Loc, DiagId) << cast<NamedDecl>(PrevDecl)->getDeclName();
Diag(PrevDecl->getLocation(), diag::note_template_param_here);
}
diff --git a/clang/test/Parser/DelayedTemplateParsing.cpp b/clang/test/Parser/DelayedTemplateParsing.cpp
index c65e80b..bcd286a 100644
--- a/clang/test/Parser/DelayedTemplateParsing.cpp
+++ b/clang/test/Parser/DelayedTemplateParsing.cpp
@@ -48,22 +48,6 @@ template <class T> void foo5() {} // expected-error {{redefinition of 'foo5'}}
-namespace Inner_Outer_same_template_param_name {
-
-template <class T>
-class Outmost {
-public:
- template <class T>
- class Inner {
- public:
- void f() {
- T* var;
- }
- };
-};
-
-}
-
namespace PR11931 {
diff --git a/clang/test/SemaCXX/MicrosoftCompatibility.cpp b/clang/test/SemaCXX/MicrosoftCompatibility.cpp
index bfdf441..453f78a 100644
--- a/clang/test/SemaCXX/MicrosoftCompatibility.cpp
+++ b/clang/test/SemaCXX/MicrosoftCompatibility.cpp
@@ -366,3 +366,21 @@ struct S {
int S::fn() { return 0; } // expected-warning {{is missing exception specification}}
}
+namespace PR43265 {
+template <int N> // expected-note {{template parameter is declared here}}
+struct Foo {
+ static const int N = 42; // expected-warning {{declaration of 'N' shadows template parameter}}
+};
+}
+
+namespace Inner_Outer_same_template_param_name {
+template <typename T> // expected-note {{template parameter is declared here}}
+struct Outmost {
+ template <typename T> // expected-warning {{declaration of 'T' shadows template parameter}}
+ struct Inner {
+ void f() {
+ T *var;
+ }
+ };
+};
+}