@@ -3979,11 +3979,23 @@ bool Sema::usesPartialOrExplicitSpecialization(
39793979 return true ;
39803980
39813981 SmallVector<ClassTemplatePartialSpecializationDecl *, 4 > PartialSpecs;
3982- ClassTemplateSpec->getSpecializedTemplate ()
3983- ->getPartialSpecializations (PartialSpecs);
3984- for (unsigned I = 0 , N = PartialSpecs.size (); I != N; ++I) {
3982+ ClassTemplateDecl *CTD = ClassTemplateSpec->getSpecializedTemplate ();
3983+ CTD->getPartialSpecializations (PartialSpecs);
3984+ for (ClassTemplatePartialSpecializationDecl *CTPSD : PartialSpecs) {
3985+ // C++ [temp.spec.partial.member]p2:
3986+ // If the primary member template is explicitly specialized for a given
3987+ // (implicit) specialization of the enclosing class template, the partial
3988+ // specializations of the member template are ignored for this
3989+ // specialization of the enclosing class template. If a partial
3990+ // specialization of the member template is explicitly specialized for a
3991+ // given (implicit) specialization of the enclosing class template, the
3992+ // primary member template and its other partial specializations are still
3993+ // considered for this specialization of the enclosing class template.
3994+ if (CTD->isMemberSpecialization () && !CTPSD->isMemberSpecialization ())
3995+ continue ;
3996+
39853997 TemplateDeductionInfo Info (Loc);
3986- if (DeduceTemplateArguments (PartialSpecs[I] ,
3998+ if (DeduceTemplateArguments (CTPSD ,
39873999 ClassTemplateSpec->getTemplateArgs ().asArray (),
39884000 Info) == TemplateDeductionResult::Success)
39894001 return true ;
@@ -4028,6 +4040,20 @@ getPatternForClassTemplateSpecialization(
40284040 TemplateSpecCandidateSet FailedCandidates (PointOfInstantiation);
40294041 for (unsigned I = 0 , N = PartialSpecs.size (); I != N; ++I) {
40304042 ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
4043+ // C++ [temp.spec.partial.member]p2:
4044+ // If the primary member template is explicitly specialized for a given
4045+ // (implicit) specialization of the enclosing class template, the
4046+ // partial specializations of the member template are ignored for this
4047+ // specialization of the enclosing class template. If a partial
4048+ // specialization of the member template is explicitly specialized for a
4049+ // given (implicit) specialization of the enclosing class template, the
4050+ // primary member template and its other partial specializations are
4051+ // still considered for this specialization of the enclosing class
4052+ // template.
4053+ if (Template->isMemberSpecialization () &&
4054+ !Partial->isMemberSpecialization ())
4055+ continue ;
4056+
40314057 TemplateDeductionInfo Info (FailedCandidates.getLocation ());
40324058 if (TemplateDeductionResult Result = S.DeduceTemplateArguments (
40334059 Partial, ClassTemplateSpec->getTemplateArgs ().asArray (), Info);
0 commit comments