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