From e307915dcfef53ec8e61aac35425eed0c893b5c8 Mon Sep 17 00:00:00 2001 From: Richard Smith <richard-llvm@metafoo.co.uk> Date: Mon, 23 Apr 2018 18:38:30 +0000 Subject: [PATCH] DR727: remove wrong assertion for use of class-scope explicit specialization without -fms-extensions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@330626 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplate.cpp | 4 ---- test/CXX/drs/dr7xx.cpp | 29 ++++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 46f2f89d68..5f739fd550 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -7561,10 +7561,6 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, ClassTemplate->AddSpecialization(Specialization, InsertPos); if (CurContext->isDependentContext()) { - // -fms-extensions permits specialization of nested classes without - // fully specializing the outer class(es). - assert(getLangOpts().MicrosoftExt && - "Only possible with -fms-extensions!"); TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name); CanonType = Context.getTemplateSpecializationType( CanonTemplate, Converted); diff --git a/test/CXX/drs/dr7xx.cpp b/test/CXX/drs/dr7xx.cpp index 982ffdddab..d02582b5b4 100644 --- a/test/CXX/drs/dr7xx.cpp +++ b/test/CXX/drs/dr7xx.cpp @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -namespace dr727 { // dr727: 7 +namespace dr727 { // dr727: partial struct A { template<typename T> struct C; // expected-note 6{{here}} template<typename T> void f(); // expected-note {{here}} @@ -48,6 +48,33 @@ namespace dr727 { // dr727: 7 template<typename T> struct A::C<T*****>; // expected-error {{not in class 'A' or an enclosing namespace}} template<typename T> int A::N<T*****>; // expected-error {{not in class 'A' or an enclosing namespace}} } + + template<typename> + struct D { + template<typename T> struct C { typename T::error e; }; // expected-error {{no members}} + template<typename T> void f() { T::error; } // expected-error {{no members}} + template<typename T> static const int N = T::error; // expected-error 2{{no members}} expected-error 0-1{{C++14}} + + template<> struct C<int> {}; + template<> void f<int>() {} + template<> static const int N<int>; + + template<typename T> struct C<T*> {}; + template<typename T> static const int N<T*>; + }; + + void d(D<int> di) { + D<int>::C<int>(); + di.f<int>(); + int a = D<int>::N<int>; // FIXME: expected-note {{instantiation of}} + + D<int>::C<int*>(); + int b = D<int>::N<int*>; + + D<int>::C<float>(); // expected-note {{instantiation of}} + di.f<float>(); // expected-note {{instantiation of}} + int c = D<int>::N<float>; // expected-note {{instantiation of}} + } } namespace dr777 { // dr777: 3.7 -- 2.40.0