Handle reinterpret_cast between integral types and pointer types.

llvm-svn: 81837
This commit is contained in:
Anders Carlsson 2009-09-15 04:48:33 +00:00
parent f82f27be3f
commit 7cd39e0721
6 changed files with 54 additions and 11 deletions

View 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 {

View 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) {

View 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!");

View 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.

View 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;
}

View File

@ -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);
}