Skip to content

Commit 445c08b

Browse files
committed
[Clang] Add support for GCC bound member functions extension
1 parent e710a5a commit 445c08b

File tree

18 files changed

+271
-29
lines changed

18 files changed

+271
-29
lines changed

clang/include/clang/AST/OperationKinds.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ CAST_OPERATION(MemberPointerToBoolean)
152152
/// many ABIs do not guarantee this on all possible intermediate types).
153153
CAST_OPERATION(ReinterpretMemberPointer)
154154

155+
/// CK_BoundPointerToMemberFunctionToFunctionPointer - Convert a bound
156+
/// member function pointer to a function pointer. This is a GNU extension.
157+
CAST_OPERATION(BoundMemberFunctionToFunctionPointer)
158+
155159
/// CK_UserDefinedConversion - Conversion using a user defined type
156160
/// conversion function.
157161
/// struct A { operator int(); }; int i = int(A());

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,7 @@ def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
795795
def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
796796
def GNUUnionCast : DiagGroup<"gnu-union-cast">;
797797
def GNUVariableSizedTypeNotAtEnd : DiagGroup<"gnu-variable-sized-type-not-at-end">;
798+
def GNUPMFCast : DiagGroup<"pmf-conversions">;
798799
def Varargs : DiagGroup<"varargs">;
799800
def XorUsedAsPow : DiagGroup<"xor-used-as-pow">;
800801

@@ -1294,22 +1295,21 @@ def C2y : DiagGroup<"c2y-extensions">;
12941295
def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">;
12951296

12961297
// A warning group for warnings about GCC extensions.
1297-
def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct,
1298-
GNUAutoType, GNUBinaryLiteral, GNUCaseRange,
1299-
GNUComplexInteger, GNUCompoundLiteralInitializer,
1300-
GNUConditionalOmittedOperand, GNUDesignator,
1301-
GNUEmptyStruct,
1302-
VLAExtension, GNUFlexibleArrayInitializer,
1303-
GNUFlexibleArrayUnionMember, GNUFoldingConstant,
1304-
GNUImaginaryConstant, GNUIncludeNext,
1305-
GNULabelsAsValue, GNULineMarker, GNUNullPointerArithmetic,
1306-
GNUOffsetofExtensions, GNUPointerArith,
1307-
RedeclaredClassMember, GNURedeclaredEnum,
1308-
GNUStatementExpression, GNUStaticFloatInit,
1309-
GNUStringLiteralOperatorTemplate, GNUUnionCast,
1310-
GNUVariableSizedTypeNotAtEnd, ZeroLengthArray,
1311-
GNUZeroLineDirective,
1312-
GNUZeroVariadicMacroArguments]>;
1298+
def GNU
1299+
: DiagGroup<
1300+
"gnu", [GNUAlignofExpression, GNUAnonymousStruct, GNUAutoType,
1301+
GNUBinaryLiteral, GNUCaseRange, GNUComplexInteger,
1302+
GNUCompoundLiteralInitializer, GNUConditionalOmittedOperand,
1303+
GNUDesignator, GNUEmptyStruct, VLAExtension,
1304+
GNUFlexibleArrayInitializer, GNUFlexibleArrayUnionMember,
1305+
GNUFoldingConstant, GNUImaginaryConstant, GNUIncludeNext,
1306+
GNULabelsAsValue, GNULineMarker, GNUNullPointerArithmetic,
1307+
GNUOffsetofExtensions, GNUPointerArith, RedeclaredClassMember,
1308+
GNURedeclaredEnum, GNUStatementExpression, GNUStaticFloatInit,
1309+
GNUStringLiteralOperatorTemplate, GNUUnionCast,
1310+
GNUVariableSizedTypeNotAtEnd, ZeroLengthArray,
1311+
GNUZeroLineDirective, GNUZeroVariadicMacroArguments,
1312+
GNUPMFCast]>;
13131313
// A warning group for warnings about code that clang accepts but gcc doesn't.
13141314
def GccCompat : DiagGroup<"gcc-compat">;
13151315

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5120,6 +5120,10 @@ def err_ovl_unresolvable : Error<
51205120
def err_bound_member_function : Error<
51215121
"reference to non-static member function must be called"
51225122
"%select{|; did you mean to call it with no arguments?}0">;
5123+
def ext_bound_member_function_conversion
5124+
: ExtWarn<"converting the bound member function %1 to a function pointer "
5125+
"%2 is a GNU extension">,
5126+
InGroup<GNUPMFCast>;
51235127
def note_possible_target_of_call : Note<"possible target for call">;
51245128
def err_no_viable_destructor : Error<
51255129
"no viable destructor found for class %0">;

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ def CK_ArrayToPointerDecay : I32EnumAttrCase<"array_to_ptrdecay", 11>;
109109
// CK_DerivedToBaseMemberPointer
110110
def CK_MemberPointerToBoolean : I32EnumAttrCase<"member_ptr_to_bool", 17>;
111111
// CK_ReinterpretMemberPointer
112+
// CK_BoundMemberFunctionToFunctionPointer
112113
// CK_UserDefinedConversion
113114
// CK_ConstructorConversion
114115
def CK_IntegralToPointer : I32EnumAttrCase<"int_to_ptr", 21>;

clang/lib/AST/Expr.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,13 @@ bool CastExpr::CastConsistency() const {
18641864
assert(getSubExpr()->getType()->isMemberPointerType());
18651865
goto CheckNoBasePath;
18661866

1867+
case CK_BoundMemberFunctionToFunctionPointer:
1868+
assert(getType()->isFunctionPointerType());
1869+
assert(getSubExpr()->getType()->isMemberPointerType() ||
1870+
getSubExpr()->getType()->isSpecificPlaceholderType(
1871+
BuiltinType::BoundMember));
1872+
goto CheckNoBasePath;
1873+
18671874
case CK_BitCast:
18681875
// Arbitrary casts to C pointer types count as bitcasts.
18691876
// Otherwise, we should only have block and ObjC pointer casts

clang/lib/AST/ExprConstant.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15103,6 +15103,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
1510315103
case CK_BaseToDerivedMemberPointer:
1510415104
case CK_DerivedToBaseMemberPointer:
1510515105
case CK_ReinterpretMemberPointer:
15106+
case CK_BoundMemberFunctionToFunctionPointer:
1510615107
case CK_ConstructorConversion:
1510715108
case CK_IntegralToPointer:
1510815109
case CK_ToVoid:
@@ -15960,6 +15961,7 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
1596015961
case CK_DerivedToBaseMemberPointer:
1596115962
case CK_MemberPointerToBoolean:
1596215963
case CK_ReinterpretMemberPointer:
15964+
case CK_BoundMemberFunctionToFunctionPointer:
1596315965
case CK_ConstructorConversion:
1596415966
case CK_IntegralToPointer:
1596515967
case CK_PointerToIntegral:

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
8383
case CK_NullToMemberPointer:
8484
case CK_NullToPointer:
8585
case CK_ReinterpretMemberPointer:
86+
case CK_BoundMemberFunctionToFunctionPointer:
8687
// Common pointer conversions, nothing to do here.
8788
// TODO: Is there any reason to treat base-to-derived conversions
8889
// specially?

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5387,6 +5387,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
53875387
case CK_BaseToDerivedMemberPointer:
53885388
case CK_MemberPointerToBoolean:
53895389
case CK_ReinterpretMemberPointer:
5390+
case CK_BoundMemberFunctionToFunctionPointer:
53905391
case CK_AnyPointerToBlockPointerCast:
53915392
case CK_ARCProduceObject:
53925393
case CK_ARCConsumeObject:

clang/lib/CodeGen/CGExprAgg.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
10431043
case CK_DerivedToBaseMemberPointer:
10441044
case CK_MemberPointerToBoolean:
10451045
case CK_ReinterpretMemberPointer:
1046+
case CK_BoundMemberFunctionToFunctionPointer:
10461047
case CK_IntegralToPointer:
10471048
case CK_PointerToIntegral:
10481049
case CK_PointerToBoolean:
@@ -1600,6 +1601,7 @@ static bool castPreservesZero(const CastExpr *CE) {
16001601
case CK_MemberPointerToBoolean:
16011602
case CK_NullToMemberPointer:
16021603
case CK_ReinterpretMemberPointer:
1604+
case CK_BoundMemberFunctionToFunctionPointer:
16031605
// FIXME: ABI-dependent.
16041606
return false;
16051607

clang/lib/CodeGen/CGExprComplex.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
575575
case CK_DerivedToBaseMemberPointer:
576576
case CK_MemberPointerToBoolean:
577577
case CK_ReinterpretMemberPointer:
578+
case CK_BoundMemberFunctionToFunctionPointer:
578579
case CK_ConstructorConversion:
579580
case CK_IntegralToPointer:
580581
case CK_PointerToIntegral:

0 commit comments

Comments
 (0)