Skip to content

Commit 0068cb2

Browse files
committedMar 20, 2015
[MSVC] Explicit specializations can be declared in any namespace (fix for http://llvm.org/PR13738)
MS compiler emits no errors in case of explicit specializations outside declaration enclosing namespaces, even when language extensions are disabled. The patch is to suppress errors and emit extension warnings if explicit specializations are not declared in the corresponding namespaces. This fixes PR13738. Patch by Alexey Frolov. Differential Revision: http://reviews.llvm.org/D8283 llvm-svn: 232800
1 parent e9fe0a2 commit 0068cb2

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed
 

‎clang/include/clang/Basic/DiagnosticSemaKinds.td

+6
Original file line numberDiff line numberDiff line change
@@ -3443,6 +3443,12 @@ def err_template_spec_redecl_out_of_scope : Error<
34433443
"variable template partial|function template|member "
34443444
"function|static data member|member class|member enumeration}0 "
34453445
"specialization of %1 not in a namespace enclosing %2">;
3446+
def ext_ms_template_spec_redecl_out_of_scope: ExtWarn<
3447+
"%select{class template|class template partial|variable template|"
3448+
"variable template partial|function template|member "
3449+
"function|static data member|member class|member enumeration}0 "
3450+
"specialization of %1 outside namespace enclosing %2 "
3451+
"is a Microsoft extension">, InGroup<Microsoft>;
34463452
def err_template_spec_redecl_global_scope : Error<
34473453
"%select{class template|class template partial|variable template|"
34483454
"variable template partial|function template|member "

‎clang/lib/Sema/SemaTemplate.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -5835,11 +5835,13 @@ static bool CheckTemplateSpecializationScope(Sema &S,
58355835
if (isa<TranslationUnitDecl>(SpecializedContext))
58365836
S.Diag(Loc, diag::err_template_spec_redecl_global_scope)
58375837
<< EntityKind << Specialized;
5838-
else if (isa<NamespaceDecl>(SpecializedContext))
5839-
S.Diag(Loc, diag::err_template_spec_redecl_out_of_scope)
5840-
<< EntityKind << Specialized
5841-
<< cast<NamedDecl>(SpecializedContext);
5842-
else
5838+
else if (isa<NamespaceDecl>(SpecializedContext)) {
5839+
int Diag = diag::err_template_spec_redecl_out_of_scope;
5840+
if (S.getLangOpts().MicrosoftExt)
5841+
Diag = diag::ext_ms_template_spec_redecl_out_of_scope;
5842+
S.Diag(Loc, Diag) << EntityKind << Specialized
5843+
<< cast<NamedDecl>(SpecializedContext);
5844+
} else
58435845
llvm_unreachable("unexpected namespace context for specialization");
58445846

58455847
S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %clang_cc1 -fsyntax-only -fms-extensions -std=c++11 -verify %s
2+
3+
namespace A {
4+
5+
template <class T>
6+
class ClassTemplate; // expected-note {{explicitly specialized declaration is here}}
7+
8+
template <class T1, class T2>
9+
class ClassTemplatePartial; // expected-note {{explicitly specialized declaration is here}}
10+
11+
template <typename T> struct X {
12+
struct MemberClass; // expected-note {{explicitly specialized declaration is here}}
13+
enum MemberEnumeration; // expected-note {{explicitly specialized declaration is here}} // expected-error {{ISO C++ forbids forward references to 'enum' types}}
14+
};
15+
16+
}
17+
18+
namespace B {
19+
20+
template <>
21+
class A::ClassTemplate<int>; // expected-warning {{class template specialization of 'ClassTemplate' outside namespace enclosing 'A' is a Microsoft extension}}
22+
23+
template <class T1>
24+
class A::ClassTemplatePartial<T1, T1 *> {}; // expected-warning {{class template partial specialization of 'ClassTemplatePartial' outside namespace enclosing 'A' is a Microsoft extension}}
25+
26+
template <>
27+
struct A::X<int>::MemberClass; // expected-warning {{member class specialization of 'MemberClass' outside namespace enclosing 'A' is a Microsoft extension}}
28+
29+
template <>
30+
enum A::X<int>::MemberEnumeration; // expected-warning {{member enumeration specialization of 'MemberEnumeration' outside namespace enclosing 'A' is a Microsoft extension}} // expected-error {{ISO C++ forbids forward references to 'enum' types}}
31+
32+
}
33+

0 commit comments

Comments
 (0)
Please sign in to comment.