@@ -84,7 +84,8 @@ static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType,
84
84
QualType OrigSrcType,
85
85
QualType OrigDestType, unsigned &msg,
86
86
CastExpr::CastKind &Kind);
87
- static TryCastResult TryStaticMemberPointerUpcast (Sema &Self, QualType SrcType,
87
+ static TryCastResult TryStaticMemberPointerUpcast (Sema &Self, Expr *&SrcExpr,
88
+ QualType SrcType,
88
89
QualType DestType,bool CStyle,
89
90
const SourceRange &OpRange,
90
91
unsigned &msg,
@@ -554,7 +555,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
554
555
// Reverse member pointer conversion. C++ 4.11 specifies member pointer
555
556
// conversion. C++ 5.2.9p9 has additional information.
556
557
// DR54's access restrictions apply here also.
557
- tcr = TryStaticMemberPointerUpcast (Self, SrcType, DestType, CStyle,
558
+ tcr = TryStaticMemberPointerUpcast (Self, SrcExpr, SrcType, DestType, CStyle,
558
559
OpRange, msg, Kind);
559
560
if (tcr != TC_NotApplicable)
560
561
return tcr;
@@ -798,12 +799,23 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
798
799
// / where B is a base class of D [...].
799
800
// /
800
801
TryCastResult
801
- TryStaticMemberPointerUpcast (Sema &Self, QualType SrcType, QualType DestType,
802
- bool CStyle, const SourceRange &OpRange,
802
+ TryStaticMemberPointerUpcast (Sema &Self, Expr *&SrcExpr, QualType SrcType,
803
+ QualType DestType, bool CStyle,
804
+ const SourceRange &OpRange,
803
805
unsigned &msg, CastExpr::CastKind &Kind) {
804
806
const MemberPointerType *DestMemPtr = DestType->getAs <MemberPointerType>();
805
807
if (!DestMemPtr)
806
808
return TC_NotApplicable;
809
+
810
+ bool WasOverloadedFunction = false ;
811
+ if (FunctionDecl *Fn
812
+ = Self.ResolveAddressOfOverloadedFunction (SrcExpr, DestType, false )) {
813
+ CXXMethodDecl *M = cast<CXXMethodDecl>(Fn);
814
+ SrcType = Self.Context .getMemberPointerType (Fn->getType (),
815
+ Self.Context .getTypeDeclType (M->getParent ()).getTypePtr ());
816
+ WasOverloadedFunction = true ;
817
+ }
818
+
807
819
const MemberPointerType *SrcMemPtr = SrcType->getAs <MemberPointerType>();
808
820
if (!SrcMemPtr) {
809
821
msg = diag::err_bad_static_cast_member_pointer_nonmp;
@@ -853,6 +865,24 @@ TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType,
853
865
return TC_Failed;
854
866
}
855
867
868
+ if (WasOverloadedFunction) {
869
+ // Resolve the address of the overloaded function again, this time
870
+ // allowing complaints if something goes wrong.
871
+ FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction (SrcExpr,
872
+ DestType,
873
+ true );
874
+ if (!Fn) {
875
+ msg = 0 ;
876
+ return TC_Failed;
877
+ }
878
+
879
+ SrcExpr = Self.FixOverloadedFunctionReference (SrcExpr, Fn);
880
+ if (!SrcExpr) {
881
+ msg = 0 ;
882
+ return TC_Failed;
883
+ }
884
+ }
885
+
856
886
Kind = CastExpr::CK_DerivedToBaseMemberPointer;
857
887
return TC_Success;
858
888
}
0 commit comments