@@ -3978,11 +3978,23 @@ bool Sema::usesPartialOrExplicitSpecialization(
3978
3978
return true ;
3979
3979
3980
3980
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
+
3984
3996
TemplateDeductionInfo Info (Loc);
3985
- if (DeduceTemplateArguments (PartialSpecs[I] ,
3997
+ if (DeduceTemplateArguments (CTPSD ,
3986
3998
ClassTemplateSpec->getTemplateArgs ().asArray (),
3987
3999
Info) == TemplateDeductionResult::Success)
3988
4000
return true ;
@@ -4027,6 +4039,20 @@ getPatternForClassTemplateSpecialization(
4027
4039
TemplateSpecCandidateSet FailedCandidates (PointOfInstantiation);
4028
4040
for (unsigned I = 0 , N = PartialSpecs.size (); I != N; ++I) {
4029
4041
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
+
4030
4056
TemplateDeductionInfo Info (FailedCandidates.getLocation ());
4031
4057
if (TemplateDeductionResult Result = S.DeduceTemplateArguments (
4032
4058
Partial, ClassTemplateSpec->getTemplateArgs ().asArray (), Info);
0 commit comments