]> granicus.if.org Git - clang/commitdiff
CastsAwayConstness shouldn't care if member pointers point into different classes...
authorSebastian Redl <sebastian.redl@getdesigned.at>
Wed, 18 Nov 2009 18:10:53 +0000 (18:10 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Wed, 18 Nov 2009 18:10:53 +0000 (18:10 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89215 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaCXXCast.cpp
test/SemaCXX/reinterpret-cast.cpp

index e5ad338502df1736ef8a5b3cb01acc63d8d8f1df..6b4f87ef1dfb28af65aa4e030909482cdb00bba3 100644 (file)
@@ -175,6 +175,30 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
   return ExprError();
 }
 
+/// UnwrapDissimilarPointerTypes - Like Sema::UnwrapSimilarPointerTypes,
+/// this removes one level of indirection from both types, provided that they're
+/// the same kind of pointer (plain or to-member). Unlike the Sema function,
+/// this one doesn't care if the two pointers-to-member don't point into the
+/// same class. This is because CastsAwayConstness doesn't care.
+bool UnwrapDissimilarPointerTypes(QualType& T1, QualType& T2) {
+  const PointerType *T1PtrType = T1->getAs<PointerType>(),
+                    *T2PtrType = T2->getAs<PointerType>();
+  if (T1PtrType && T2PtrType) {
+    T1 = T1PtrType->getPointeeType();
+    T2 = T2PtrType->getPointeeType();
+    return true;
+  }
+
+  const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(),
+                          *T2MPType = T2->getAs<MemberPointerType>();
+  if (T1MPType && T2MPType) {
+    T1 = T1MPType->getPointeeType();
+    T2 = T2MPType->getPointeeType();
+    return true;
+  }
+  return false;
+}
+
 /// CastsAwayConstness - Check if the pointer conversion from SrcType to
 /// DestType casts away constness as defined in C++ 5.2.11p8ff. This is used by
 /// the cast checkers.  Both arguments must denote pointer (possibly to member)
@@ -195,7 +219,7 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) {
   llvm::SmallVector<Qualifiers, 8> cv1, cv2;
 
   // Find the qualifications.
-  while (Self.UnwrapSimilarPointerTypes(UnwrappedSrcType, UnwrappedDestType)) {
+  while (UnwrapDissimilarPointerTypes(UnwrappedSrcType, UnwrappedDestType)) {
     cv1.push_back(UnwrappedSrcType.getQualifiers());
     cv2.push_back(UnwrappedDestType.getQualifiers());
   }
index 91b72cc02207c2b84d7ad894d015a0df622e6cf4..be960a3af8b54f89d2767f12fef11653f002a96c 100644 (file)
@@ -88,3 +88,9 @@ void memptrs()
   (void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (struct structure::*)()' is not allowed}}
   (void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int struct structure::*' is not allowed}}
 }
+
+// PR5545
+class A;
+class B;
+void (A::*a)();
+void (B::*b)() = reinterpret_cast<void (B::*)()>(a);