]> granicus.if.org Git - clang/commitdiff
Error out if reinterpret_casting between member pointers of two different
authorCharles Davis <cdavis@mines.edu>
Mon, 16 Aug 2010 05:30:44 +0000 (05:30 +0000)
committerCharles Davis <cdavis@mines.edu>
Mon, 16 Aug 2010 05:30:44 +0000 (05:30 +0000)
sizes.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111119 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaCXXCast.cpp
test/SemaCXX/member-pointer-ms.cpp

index 7cdc9f49c7295d8e400664c47da00d690e8ddc30..1d8597962103d8a103ab23b4b02e9066a5828d5e 100644 (file)
@@ -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.
index 59df294772e809e15e69c2aca135fb203c9d7db1..54018005dcb0bacc7aac4bc7cbf9290f9b6dd002 100644 (file)
@@ -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;
index 8987f6d66fdb804294323ddd7be2c2b5105ec4b6..3b2d0fceb9788afc40d6ccd544126eb6b4a8d8ac 100644 (file)
@@ -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<void (C::*)()>(paf); //expected-error{{cannot reinterpret_cast from member pointer type}}