forked from OSchip/llvm-project
Handle reinterpret_cast between integral types and pointer types.
llvm-svn: 81837
This commit is contained in:
parent
f82f27be3f
commit
7cd39e0721
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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!");
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue