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