]> granicus.if.org Git - clang/commitdiff
Handle reinterpret_cast between integral types and pointer types.
authorAnders Carlsson <andersca@mac.com>
Tue, 15 Sep 2009 04:48:33 +0000 (04:48 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 15 Sep 2009 04:48:33 +0000 (04:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81837 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
include/clang/AST/ExprCXX.h
lib/AST/Expr.cpp
lib/CodeGen/CGExprScalar.cpp
lib/Sema/SemaCXXCast.cpp
test/CodeGenCXX/reinterpret-cast.cpp [new file with mode: 0644]

index 81aecf7f31e822e99f2f308b6a81ecc7ddd0f316..3e122c1f53a6a6946148613a102d582f53f319da 100644 (file)
@@ -1368,7 +1368,13 @@ public:
     CK_UserDefinedConversion,
 
     /// CK_ConstructorConversion - Conversion by constructor
-    CK_ConstructorConversion
+    CK_ConstructorConversion,
+    
+    /// CK_IntegralToPointer - Integral to pointer
+    CK_IntegralToPointer,
+    
+    /// CK_PointerToIntegral - Pointer to integral
+    CK_PointerToIntegral
   };
 
   struct CastInfo {
index 871014d6c81612699c15c5ee818e126aa3009092..5e3dec770574bc1854965d372c7877fe1d542c31 100644 (file)
@@ -185,9 +185,9 @@ public:
 /// @c reinterpret_cast<int>(VoidPtr).
 class CXXReinterpretCastExpr : public CXXNamedCastExpr {
 public:
-  CXXReinterpretCastExpr(QualType ty, Expr *op, QualType writtenTy,
-                         SourceLocation l)
-    : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, CK_BitCast, op,
+  CXXReinterpretCastExpr(QualType ty, CastKind kind, Expr *op, 
+                         QualType writtenTy, SourceLocation l)
+    : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op,
                        writtenTy, l) {}
 
   static bool classof(const Stmt *T) {
index 620b5b8901619b859c9f4e4335ca6d38ef1e17c4..0ac896c78388da347285273ec7f422150d2c56ff 100644 (file)
@@ -422,6 +422,10 @@ const char *CastExpr::getCastKindName() const {
     return "UserDefinedConversion";
   case CastExpr::CK_ConstructorConversion:
     return "ConstructorConversion";
+  case CastExpr::CK_IntegralToPointer:
+    return "IntegralToPointer";
+  case CastExpr::CK_PointerToIntegral:
+    return "PointerToIntegral";
   }
 
   assert(0 && "Unhandled cast kind!");
index 7f9b66468b8cf33f8ec19064e9a0fd416bde84cb..682d14ca2e5a34b2f68f8d71d430a56493e66d0c 100644 (file)
@@ -625,6 +625,12 @@ Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy,
 
   switch (Kind) {
   default:
+    // FIXME: Assert here.
+    // assert(0 && "Unhandled cast kind!");
+    break;
+  case CastExpr::CK_Unknown:
+    // FIXME: We should really assert here - Unknown casts should never get
+    // as far as to codegen.
     break;
   case CastExpr::CK_BitCast: {
     Value *Src = Visit(const_cast<Expr*>(E));
@@ -685,6 +691,16 @@ Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy,
                                         NullCheckValue);
   }
 
+  case CastExpr::CK_IntegralToPointer: {
+    Value *Src = Visit(const_cast<Expr*>(E));
+    return Builder.CreateIntToPtr(Src, ConvertType(DestTy));
+  }
+
+  case CastExpr::CK_PointerToIntegral: {
+    Value *Src = Visit(const_cast<Expr*>(E));
+    return Builder.CreatePtrToInt(Src, ConvertType(DestTy));
+  }
+  
   }
 
   // Handle cases where the source is an non-complex type.
index 0ae5d343cade7c63758f1e978b15708aa415a702..dbd6c6fde5c60167f31d7aa41750e55bac45908a 100644 (file)
@@ -41,7 +41,8 @@ static void CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                            const SourceRange &DestRange);
 static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                                  const SourceRange &OpRange,
-                                 const SourceRange &DestRange);
+                                 const SourceRange &DestRange,
+                                 CastExpr::CastKind &Kind);
 static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                             const SourceRange &OpRange,
                             CastExpr::CastKind &Kind,
@@ -135,13 +136,14 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
     return Owned(new (Context)CXXDynamicCastExpr(DestType.getNonReferenceType(),
                                                  Kind, Ex, DestType, OpLoc));
   }
-  case tok::kw_reinterpret_cast:
+  case tok::kw_reinterpret_cast: {
+    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
     if (!TypeDependent)
-      CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange);
+      CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange, Kind);
     return Owned(new (Context) CXXReinterpretCastExpr(
                                   DestType.getNonReferenceType(),
-                                  Ex, DestType, OpLoc));
-
+                                  Kind, Ex, DestType, OpLoc));
+  }
   case tok::kw_static_cast: {
     CastExpr::CastKind Kind = CastExpr::CK_Unknown;
     if (!TypeDependent) {
@@ -355,11 +357,11 @@ CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
 /// char *bytes = reinterpret_cast\<char*\>(int_ptr);
 void
 CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
-                     const SourceRange &OpRange, const SourceRange &DestRange) {
+                     const SourceRange &OpRange, const SourceRange &DestRange,
+                     CastExpr::CastKind &Kind) {
   if (!DestType->isLValueReferenceType())
     Self.DefaultFunctionArrayConversion(SrcExpr);
 
-  CastExpr::CastKind Kind = CastExpr::CK_Unknown;
   unsigned msg = diag::err_bad_cxx_cast_generic;
   if (TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/false, Kind,
                          OpRange, msg)
@@ -950,6 +952,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
       msg = diag::err_bad_reinterpret_cast_small_int;
       return TC_Failed;
     }
+    Kind = CastExpr::CK_PointerToIntegral;
     return TC_Success;
   }
 
@@ -982,6 +985,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
       msg = diag::err_bad_reinterpret_cast_small_int;
       return TC_Failed;
     }
+    Kind = CastExpr::CK_PointerToIntegral;
     return TC_Success;
   }
 
@@ -989,6 +993,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
     assert(destIsPtr && "One type must be a pointer");
     // C++ 5.2.10p5: A value of integral or enumeration type can be explicitly
     //   converted to a pointer.
+    Kind = CastExpr::CK_IntegralToPointer;
     return TC_Success;
   }
 
diff --git a/test/CodeGenCXX/reinterpret-cast.cpp b/test/CodeGenCXX/reinterpret-cast.cpp
new file mode 100644 (file)
index 0000000..ae3ab2f
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: clang-cc -emit-llvm -o - %s -std=c++0x
+void *f1(unsigned long l) {
+  return reinterpret_cast<void *>(l);
+}
+
+unsigned long f2() {
+  return reinterpret_cast<unsigned long>(nullptr);
+}
+
+unsigned long f3(void *p) {
+  return reinterpret_cast<unsigned long>(p);
+}
\ No newline at end of file