forked from OSchip/llvm-project
[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
This commit is contained in:
parent
18f5204db4
commit
b6a8152b8b
|
@ -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">;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue