diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7cdc9f49c729..1d8597962103 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2342,6 +2342,9 @@ def err_bad_static_cast_pointer_nonpointer : Error< "cannot cast from type %1 to pointer type %2">; def err_bad_static_cast_member_pointer_nonmp : Error< "cannot cast from type %1 to member pointer type %2">; +def err_bad_cxx_cast_member_pointer_size : Error< + "cannot %select{||reinterpret_cast||C-style cast|}0 from member pointer " + "type %1 to member pointer type %2 of different size">; def err_bad_static_cast_incomplete : Error<"%0 is an incomplete type">; // These messages don't adhere to the pattern. diff --git a/clang/lib/Sema/SemaCXXCast.cpp b/clang/lib/Sema/SemaCXXCast.cpp index 59df294772e8..54018005dcb0 100644 --- a/clang/lib/Sema/SemaCXXCast.cpp +++ b/clang/lib/Sema/SemaCXXCast.cpp @@ -1103,6 +1103,13 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, return TC_Failed; } + // Don't allow casting between member pointers of different sizes. + if (Self.Context.getTypeSize(DestMemPtr) != + Self.Context.getTypeSize(SrcMemPtr)) { + msg = diag::err_bad_cxx_cast_member_pointer_size; + return TC_Failed; + } + // A valid member pointer cast. Kind = IsLValueCast? CastExpr::CK_LValueBitCast : CastExpr::CK_BitCast; return TC_Success; diff --git a/clang/test/SemaCXX/member-pointer-ms.cpp b/clang/test/SemaCXX/member-pointer-ms.cpp index 8987f6d66fdb..3b2d0fceb978 100644 --- a/clang/test/SemaCXX/member-pointer-ms.cpp +++ b/clang/test/SemaCXX/member-pointer-ms.cpp @@ -4,3 +4,11 @@ struct A; //expected-note{{forward declaration of 'A'}} int A::*pai1; //expected-error{{incomplete type 'A'}} +// Test that we don't allow reinterpret_casts from pointers of one size to +// pointers of a different size. +struct A {}; +struct B {}; +struct C: A, B {}; + +void (A::*paf)(); +void (C::*pcf)() = reinterpret_cast(paf); //expected-error{{cannot reinterpret_cast from member pointer type}}