@@ -150,6 +150,11 @@ namespace {
150
150
bool isPlaceholder(BuiltinType::Kind K) const {
151
151
return PlaceholderKind == K;
152
152
}
153
+ bool isBoundPMFConversion() const {
154
+ return isPlaceholder(BuiltinType::BoundMember) &&
155
+ DestType->isFunctionPointerType() &&
156
+ SrcExpr.get()->isBoundMemberFunction(Self.Context);
157
+ }
153
158
154
159
// Language specific cast restrictions for address spaces.
155
160
void checkAddressSpaceCast(QualType SrcType, QualType DestType);
@@ -243,13 +248,11 @@ static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType,
243
248
QualType OrigDestType, unsigned &msg,
244
249
CastKind &Kind,
245
250
CXXCastPath &BasePath);
246
- static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr,
247
- QualType SrcType,
248
- QualType DestType,bool CStyle,
249
- SourceRange OpRange,
250
- unsigned &msg,
251
- CastKind &Kind,
252
- CXXCastPath &BasePath);
251
+ static TryCastResult
252
+ TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType,
253
+ QualType DestType, bool CStyle,
254
+ SourceRange OpRange, unsigned &msg, CastKind &Kind,
255
+ CXXCastPath &BasePath);
253
256
254
257
static TryCastResult
255
258
TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
@@ -1198,9 +1201,10 @@ static unsigned int checkCastFunctionType(Sema &Self, const ExprResult &SrcExpr,
1198
1201
/// like this:
1199
1202
/// char *bytes = reinterpret_cast\<char*\>(int_ptr);
1200
1203
void CastOperation::CheckReinterpretCast() {
1201
- if (ValueKind == VK_PRValue && !isPlaceholder(BuiltinType::Overload))
1202
- SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1203
- else
1204
+ if (ValueKind == VK_PRValue) {
1205
+ if (!isPlaceholder(BuiltinType::Overload) && !isBoundPMFConversion())
1206
+ SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1207
+ } else
1204
1208
checkNonOverloadPlaceholders();
1205
1209
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
1206
1210
return;
@@ -2327,6 +2331,16 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
2327
2331
return TC_Success;
2328
2332
}
2329
2333
2334
+ // GNU extension: check if we can convert a pmf to a function pointer
2335
+ if (DestType->isFunctionPointerType() &&
2336
+ (SrcType->isMemberFunctionPointerType() ||
2337
+ SrcExpr.get()->isBoundMemberFunction(Self.Context)) &&
2338
+ Self.Context.getTargetInfo().getCXXABI().isItaniumFamily()) {
2339
+ Kind = CK_BoundMemberFunctionToFunctionPointer;
2340
+ msg = diag::ext_bound_member_function_conversion;
2341
+ return TC_Extension;
2342
+ }
2343
+
2330
2344
// See below for the enumeral issue.
2331
2345
if (SrcType->isNullPtrType() && DestType->isIntegralType(Self.Context)) {
2332
2346
// C++0x 5.2.10p4: A pointer can be explicitly converted to any integral
@@ -2693,9 +2707,11 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
2693
2707
return;
2694
2708
}
2695
2709
2696
- checkNonOverloadPlaceholders();
2697
- if (SrcExpr.isInvalid())
2698
- return;
2710
+ if (!isBoundPMFConversion()) {
2711
+ checkNonOverloadPlaceholders();
2712
+ if (SrcExpr.isInvalid())
2713
+ return;
2714
+ }
2699
2715
}
2700
2716
2701
2717
// C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
@@ -2733,7 +2749,7 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
2733
2749
}
2734
2750
2735
2751
if (ValueKind == VK_PRValue && !DestType->isRecordType() &&
2736
- !isPlaceholder(BuiltinType::Overload)) {
2752
+ !isPlaceholder(BuiltinType::Overload) && !isBoundPMFConversion() ) {
2737
2753
SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
2738
2754
if (SrcExpr.isInvalid())
2739
2755
return;
@@ -2791,12 +2807,16 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
2791
2807
return;
2792
2808
2793
2809
if (tcr == TC_NotApplicable) {
2794
- // ... or if that is not possible, a static_cast, ignoring const and
2795
- // addr space, ...
2796
- tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange, msg, Kind,
2797
- BasePath, ListInitialization);
2798
- if (SrcExpr.isInvalid())
2799
- return;
2810
+ // FIXME: Bound member function to function pointer conversion is blocked
2811
+ // by an immediate error inside ``Sema::CheckPlaceholderExpr``.
2812
+ if (!isBoundPMFConversion()) {
2813
+ // ... or if that is not possible, a static_cast, ignoring const and
2814
+ // addr space, ...
2815
+ tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange, msg, Kind,
2816
+ BasePath, ListInitialization);
2817
+ if (SrcExpr.isInvalid())
2818
+ return;
2819
+ }
2800
2820
2801
2821
if (tcr == TC_NotApplicable) {
2802
2822
// ... and finally a reinterpret_cast, ignoring const and addr space.
0 commit comments