mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 04:56:07 +00:00
Introduce a null-to-pointer implicit cast kind.
llvm-svn: 118966
This commit is contained in:
parent
1aa5863a3e
commit
e84af4e486
@ -1982,6 +1982,7 @@ private:
|
||||
case CK_ArrayToPointerDecay:
|
||||
case CK_FunctionToPointerDecay:
|
||||
case CK_NullToMemberPointer:
|
||||
case CK_NullToPointer:
|
||||
case CK_UserDefinedConversion:
|
||||
case CK_ConstructorConversion:
|
||||
case CK_IntegralToPointer:
|
||||
|
@ -57,6 +57,9 @@ enum CastKind {
|
||||
/// CK_FunctionToPointerDecay - Function to pointer decay.
|
||||
CK_FunctionToPointerDecay,
|
||||
|
||||
/// CK_NullToPointer - Null pointer to pointer.
|
||||
CK_NullToPointer,
|
||||
|
||||
/// CK_NullToMemberPointer - Null pointer to member pointer.
|
||||
CK_NullToMemberPointer,
|
||||
|
||||
|
@ -764,6 +764,8 @@ const char *CastExpr::getCastKindName() const {
|
||||
return "FunctionToPointerDecay";
|
||||
case CK_NullToMemberPointer:
|
||||
return "NullToMemberPointer";
|
||||
case CK_NullToPointer:
|
||||
return "NullToPointer";
|
||||
case CK_BaseToDerivedMemberPointer:
|
||||
return "BaseToDerivedMemberPointer";
|
||||
case CK_DerivedToBaseMemberPointer:
|
||||
|
@ -604,6 +604,12 @@ bool PointerExprEvaluator::VisitCastExpr(CastExpr* E) {
|
||||
return true;
|
||||
}
|
||||
|
||||
case CK_NullToPointer: {
|
||||
Result.Base = 0;
|
||||
Result.Offset = CharUnits::Zero();
|
||||
return true;
|
||||
}
|
||||
|
||||
case CK_IntegralToPointer: {
|
||||
APValue Value;
|
||||
if (!EvaluateIntegerOrLValue(SubExpr, Value, Info))
|
||||
|
@ -2518,6 +2518,7 @@ void GRExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
|
||||
case CK_BitCast:
|
||||
case CK_LValueBitCast:
|
||||
case CK_IntegralCast:
|
||||
case CK_NullToPointer:
|
||||
case CK_IntegralToPointer:
|
||||
case CK_PointerToIntegral:
|
||||
case CK_IntegralToFloating:
|
||||
|
@ -1806,6 +1806,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
|
||||
case CK_ArrayToPointerDecay:
|
||||
case CK_FunctionToPointerDecay:
|
||||
case CK_NullToMemberPointer:
|
||||
case CK_NullToPointer:
|
||||
case CK_IntegralToPointer:
|
||||
case CK_PointerToIntegral:
|
||||
case CK_VectorSplat:
|
||||
|
@ -48,6 +48,13 @@ struct BinOpInfo {
|
||||
const Expr *E; // Entire expr, for error unsupported. May not be binop.
|
||||
};
|
||||
|
||||
static bool MustVisitNullValue(const Expr *E) {
|
||||
// If a null pointer expression's type is the C++0x nullptr_t, then
|
||||
// it's not necessarily a simple constant and it must be evaluated
|
||||
// for its potential side effects.
|
||||
return E->getType()->isNullPtrType();
|
||||
}
|
||||
|
||||
class ScalarExprEmitter
|
||||
: public StmtVisitor<ScalarExprEmitter, Value*> {
|
||||
CodeGenFunction &CGF;
|
||||
@ -1044,10 +1051,15 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
|
||||
case CK_FunctionToPointerDecay:
|
||||
return EmitLValue(E).getAddress();
|
||||
|
||||
case CK_NullToPointer:
|
||||
if (MustVisitNullValue(E))
|
||||
(void) Visit(E);
|
||||
|
||||
return llvm::ConstantPointerNull::get(
|
||||
cast<llvm::PointerType>(ConvertType(DestTy)));
|
||||
|
||||
case CK_NullToMemberPointer: {
|
||||
// If the subexpression's type is the C++0x nullptr_t, emit the
|
||||
// subexpression, which may have side effects.
|
||||
if (E->getType()->isNullPtrType())
|
||||
if (MustVisitNullValue(E))
|
||||
(void) Visit(E);
|
||||
|
||||
const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>();
|
||||
|
@ -1131,7 +1131,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
|
||||
|
||||
// Is the source an overloaded name? (i.e. &foo)
|
||||
// If so, reinterpret_cast can not help us here (13.4, p1, bullet 5)
|
||||
if (SrcType == Self.Context.OverloadTy )
|
||||
if (SrcType == Self.Context.OverloadTy)
|
||||
return TC_NotApplicable;
|
||||
|
||||
if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) {
|
||||
@ -1270,6 +1270,8 @@ 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.
|
||||
// C++ 5.2.10p9: [Note: ...a null pointer constant of integral type is not
|
||||
// necessarily converted to a null pointer value.]
|
||||
Kind = CK_IntegralToPointer;
|
||||
return TC_Success;
|
||||
}
|
||||
|
@ -4003,7 +4003,8 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
|
||||
}
|
||||
|
||||
static CastKind getScalarCastKind(ASTContext &Context,
|
||||
QualType SrcTy, QualType DestTy) {
|
||||
Expr *Src, QualType DestTy) {
|
||||
QualType SrcTy = Src->getType();
|
||||
if (Context.hasSameUnqualifiedType(SrcTy, DestTy))
|
||||
return CK_NoOp;
|
||||
|
||||
@ -4019,8 +4020,11 @@ static CastKind getScalarCastKind(ASTContext &Context,
|
||||
if (SrcTy->isIntegerType()) {
|
||||
if (DestTy->isIntegerType())
|
||||
return CK_IntegralCast;
|
||||
if (DestTy->hasPointerRepresentation())
|
||||
if (DestTy->hasPointerRepresentation()) {
|
||||
if (Src->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
|
||||
return CK_NullToPointer;
|
||||
return CK_IntegralToPointer;
|
||||
}
|
||||
if (DestTy->isRealFloatingType())
|
||||
return CK_IntegralToFloating;
|
||||
}
|
||||
@ -4131,7 +4135,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
|
||||
<< castType << castExpr->getSourceRange();
|
||||
}
|
||||
|
||||
Kind = getScalarCastKind(Context, castExpr->getType(), castType);
|
||||
Kind = getScalarCastKind(Context, castExpr, castType);
|
||||
|
||||
if (Kind == CK_Unknown || Kind == CK_BitCast)
|
||||
CheckCastAlign(castExpr, castType, TyR);
|
||||
@ -4185,7 +4189,7 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
|
||||
|
||||
QualType DestElemTy = DestTy->getAs<ExtVectorType>()->getElementType();
|
||||
ImpCastExprToType(CastExpr, DestElemTy,
|
||||
getScalarCastKind(Context, SrcTy, DestElemTy));
|
||||
getScalarCastKind(Context, CastExpr, DestElemTy));
|
||||
|
||||
Kind = CK_VectorSplat;
|
||||
return false;
|
||||
@ -4533,7 +4537,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
|
||||
return LHSTy;
|
||||
}
|
||||
|
||||
// GCC compatibility: soften pointer/integer mismatch.
|
||||
// GCC compatibility: soften pointer/integer mismatch. Note that
|
||||
// null pointers have been filtered out by this point.
|
||||
if (RHSTy->isPointerType() && LHSTy->isIntegerType()) {
|
||||
Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
|
||||
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
|
||||
@ -5104,7 +5109,7 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, Expr *&rExpr) {
|
||||
|
||||
if (rExpr->isNullPointerConstant(Context,
|
||||
Expr::NPC_ValueDependentIsNull)) {
|
||||
ImpCastExprToType(rExpr, it->getType(), CK_IntegralToPointer);
|
||||
ImpCastExprToType(rExpr, it->getType(), CK_NullToPointer);
|
||||
InitField = *it;
|
||||
break;
|
||||
}
|
||||
@ -5827,7 +5832,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
|
||||
ImpCastExprToType(rex, lType,
|
||||
lType->isMemberPointerType()
|
||||
? CK_NullToMemberPointer
|
||||
: CK_IntegralToPointer);
|
||||
: CK_NullToPointer);
|
||||
return ResultTy;
|
||||
}
|
||||
if (LHSIsNull &&
|
||||
@ -5836,7 +5841,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
|
||||
ImpCastExprToType(lex, rType,
|
||||
rType->isMemberPointerType()
|
||||
? CK_NullToMemberPointer
|
||||
: CK_IntegralToPointer);
|
||||
: CK_NullToPointer);
|
||||
return ResultTy;
|
||||
}
|
||||
|
||||
@ -5951,21 +5956,23 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
|
||||
}
|
||||
|
||||
if (lType->isIntegerType())
|
||||
ImpCastExprToType(lex, rType, CK_IntegralToPointer);
|
||||
ImpCastExprToType(lex, rType,
|
||||
LHSIsNull ? CK_NullToPointer : CK_IntegralToPointer);
|
||||
else
|
||||
ImpCastExprToType(rex, lType, CK_IntegralToPointer);
|
||||
ImpCastExprToType(rex, lType,
|
||||
RHSIsNull ? CK_NullToPointer : CK_IntegralToPointer);
|
||||
return ResultTy;
|
||||
}
|
||||
|
||||
// Handle block pointers.
|
||||
if (!isRelational && RHSIsNull
|
||||
&& lType->isBlockPointerType() && rType->isIntegerType()) {
|
||||
ImpCastExprToType(rex, lType, CK_IntegralToPointer);
|
||||
ImpCastExprToType(rex, lType, CK_NullToPointer);
|
||||
return ResultTy;
|
||||
}
|
||||
if (!isRelational && LHSIsNull
|
||||
&& lType->isIntegerType() && rType->isBlockPointerType()) {
|
||||
ImpCastExprToType(lex, rType, CK_IntegralToPointer);
|
||||
ImpCastExprToType(lex, rType, CK_NullToPointer);
|
||||
return ResultTy;
|
||||
}
|
||||
return InvalidOperands(Loc, lex, rex);
|
||||
|
@ -2750,14 +2750,14 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
|
||||
if (T2->isMemberPointerType())
|
||||
ImpCastExprToType(E1, T2, CK_NullToMemberPointer);
|
||||
else
|
||||
ImpCastExprToType(E1, T2, CK_IntegralToPointer);
|
||||
ImpCastExprToType(E1, T2, CK_NullToPointer);
|
||||
return T2;
|
||||
}
|
||||
if (E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
|
||||
if (T1->isMemberPointerType())
|
||||
ImpCastExprToType(E2, T1, CK_NullToMemberPointer);
|
||||
else
|
||||
ImpCastExprToType(E2, T1, CK_IntegralToPointer);
|
||||
ImpCastExprToType(E2, T1, CK_NullToPointer);
|
||||
return T1;
|
||||
}
|
||||
|
||||
|
@ -1014,9 +1014,13 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
|
||||
if (ReceiverType->isPointerType())
|
||||
ImpCastExprToType(Receiver, Context.getObjCIdType(),
|
||||
CK_BitCast);
|
||||
else
|
||||
else {
|
||||
// TODO: specialized warning on null receivers?
|
||||
bool IsNull = Receiver->isNullPointerConstant(Context,
|
||||
Expr::NPC_ValueDependentIsNull);
|
||||
ImpCastExprToType(Receiver, Context.getObjCIdType(),
|
||||
CK_IntegralToPointer);
|
||||
IsNull ? CK_NullToPointer : CK_IntegralToPointer);
|
||||
}
|
||||
ReceiverType = Receiver->getType();
|
||||
}
|
||||
else if (getLangOptions().CPlusPlus &&
|
||||
|
Loading…
x
Reference in New Issue
Block a user