[cfe-commits] r63150 - in /cfe/trunk: lib/Sema/SemaNamedCast.cpp test/SemaCXX/reinterpret-cast.cpp www/cxx_status.html

Sebastian Redl sebastian.redl at getdesigned.at
Tue Jan 27 15:18:31 PST 2009


Author: cornedbee
Date: Tue Jan 27 17:18:31 2009
New Revision: 63150

URL: http://llvm.org/viewvc/llvm-project?rev=63150&view=rev
Log:
Add handling of member pointers to reinterpret_cast.

Modified:
    cfe/trunk/lib/Sema/SemaNamedCast.cpp
    cfe/trunk/test/SemaCXX/reinterpret-cast.cpp
    cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/lib/Sema/SemaNamedCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaNamedCast.cpp?rev=63150&r1=63149&r2=63150&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaNamedCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaNamedCast.cpp Tue Jan 27 17:18:31 2009
@@ -237,6 +237,32 @@
   // Canonicalize source for comparison.
   SrcType = Self.Context.getCanonicalType(SrcType);
 
+  const MemberPointerType *DestMemPtr = DestType->getAsMemberPointerType(),
+                          *SrcMemPtr = SrcType->getAsMemberPointerType();
+  if (DestMemPtr && SrcMemPtr) {
+    // C++ 5.2.10p9: An rvalue of type "pointer to member of X of type T1"
+    //   can be explicitly converted to an rvalue of type "pointer to member
+    //   of Y of type T2" if T1 and T2 are both function types or both object
+    //   types.
+    if (DestMemPtr->getPointeeType()->isFunctionType() !=
+        SrcMemPtr->getPointeeType()->isFunctionType()) {
+      Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_generic)
+        << "reinterpret_cast" << OrigDestType << OrigSrcType << OpRange;
+      return;
+    }
+
+    // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away
+    //   constness.
+    if (CastsAwayConstness(Self, SrcType, DestType)) {
+      Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_const_away)
+        << "reinterpret_cast" << OrigDestType << OrigSrcType << OpRange;
+      return;
+    }
+
+    // A valid member pointer cast.
+    return;
+  }
+
   bool destIsPtr = DestType->isPointerType();
   bool srcIsPtr = SrcType->isPointerType();
   if (!destIsPtr && !srcIsPtr) {
@@ -253,8 +279,8 @@
     // restrictions, a cast to the same type is allowed. The intent is not
     // entirely clear here, since all other paragraphs explicitly forbid casts
     // to the same type. However, the behavior of compilers is pretty consistent
-    // on this point: allow same-type conversion if the involved are pointers,
-    // disallow otherwise.
+    // on this point: allow same-type conversion if the involved types are
+    // pointers, disallow otherwise.
     return;
   }
 
@@ -304,8 +330,6 @@
       return;
     }
 
-    // FIXME: Handle member pointers.
-
     // C++0x 5.2.10p8: Converting a pointer to a function into a pointer to
     //   an object type or vice versa is conditionally-supported.
     // Compilers support it in C++03 too, though, because it's necessary for
@@ -319,8 +343,6 @@
     return;
   }
 
-  // FIXME: Handle member pointers.
-
   if (DestType->isFunctionPointerType()) {
     // See above.
     if (!Self.getLangOptions().CPlusPlus0x) {
@@ -337,18 +359,21 @@
   // object pointers.
 }
 
-/// 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 types.
+/// 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)
+/// types.
 bool
 CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType)
 {
- // Casting away constness is defined in C++ 5.2.11p8 with reference to
-  // C++ 4.4.
-  // We piggyback on Sema::IsQualificationConversion for this, since the rules
-  // are non-trivial. So first we construct Tcv *...cv* as described in
-  // C++ 5.2.11p8.
+  // Casting away constness is defined in C++ 5.2.11p8 with reference to
+  // C++ 4.4. We piggyback on Sema::IsQualificationConversion for this, since
+  // the rules are non-trivial. So first we construct Tcv *...cv* as described
+  // in C++ 5.2.11p8.
+  assert((SrcType->isPointerType() || SrcType->isMemberPointerType()) &&
+         "Source type is not pointer or pointer to member.");
+  assert((DestType->isPointerType() || DestType->isMemberPointerType()) &&
+         "Destination type is not pointer or pointer to member.");
 
   QualType UnwrappedSrcType = SrcType, UnwrappedDestType = DestType;
   llvm::SmallVector<unsigned, 8> cv1, cv2;

Modified: cfe/trunk/test/SemaCXX/reinterpret-cast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/reinterpret-cast.cpp?rev=63150&r1=63149&r2=63150&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/reinterpret-cast.cpp (original)
+++ cfe/trunk/test/SemaCXX/reinterpret-cast.cpp Tue Jan 27 17:18:31 2009
@@ -70,3 +70,21 @@
   // Bad: from rvalue
   (void)reinterpret_cast<int&>(&c); // expected-error {{reinterpret_cast from rvalue to reference type 'int &'}}
 }
+
+void memptrs()
+{
+  const int structure::*psi = 0;
+  (void)reinterpret_cast<const float structure::*>(psi);
+  (void)reinterpret_cast<int structure::*>(psi); // expected-error {{reinterpret_cast from 'int const struct structure::*' to 'int struct structure::*' casts away constness}}
+
+  void (structure::*psf)() = 0;
+  (void)reinterpret_cast<int (structure::*)()>(psf);
+
+  (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'int const struct structure::*' to 'void (struct structure::*)(void)' is not allowed}}
+  (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (struct structure::*)(void)' to 'int struct structure::*' is not allowed}}
+
+  // Cannot cast from integers to member pointers, not even the null pointer
+  // literal.
+  (void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (struct structure::*)(void)' is not allowed}}
+  (void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int struct structure::*' is not allowed}}
+}

Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=63150&r1=63149&r2=63150&view=diff

==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Tue Jan 27 17:18:31 2009
@@ -579,10 +579,10 @@
 <tr>
   <td>    5.2.10 [expr.reinterpret.cast]</td>
   <td class="complete" align="center">&#x2713;</td>
-  <td class="advanced" align="center"></td>
-  <td class="advanced" align="center"></td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td class="complete" align="center">&#x2713;</td>
+  <td></td>
   <td></td>
-  <td>Missing member pointer conversions</td>
 </tr>
 <tr>
   <td>    5.2.11 [expr.const.cast]</td>





More information about the cfe-commits mailing list