Propagate SourceLocations through to get a Loc on float_cast_overflow

Summary:
float_cast_overflow is the only UBSan check without a source location attached.
This patch propagates SourceLocations where necessary to get them to the
EmitCheck() call.

Reviewers: rsmith, ABataev, rjmccall

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D11757

llvm-svn: 244568
This commit is contained in:
Filipe Cabecinhas 2015-08-11 04:19:28 +00:00
parent 7317de6c15
commit 7af183d841
7 changed files with 152 additions and 110 deletions

View File

@ -96,10 +96,12 @@ llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
} }
QualType BoolTy = getContext().BoolTy; QualType BoolTy = getContext().BoolTy;
SourceLocation Loc = E->getExprLoc();
if (!E->getType()->isAnyComplexType()) if (!E->getType()->isAnyComplexType())
return EmitScalarConversion(EmitScalarExpr(E), E->getType(), BoolTy); return EmitScalarConversion(EmitScalarExpr(E), E->getType(), BoolTy, Loc);
return EmitComplexToScalarConversion(EmitComplexExpr(E), E->getType(),BoolTy); return EmitComplexToScalarConversion(EmitComplexExpr(E), E->getType(), BoolTy,
Loc);
} }
/// EmitIgnoredExpr - Emit code to compute the specified expression, /// EmitIgnoredExpr - Emit code to compute the specified expression,

View File

@ -85,10 +85,10 @@ public:
/// Emit a cast from complex value Val to DestType. /// Emit a cast from complex value Val to DestType.
ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType, ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
QualType DestType); QualType DestType, SourceLocation Loc);
/// Emit a cast from scalar value Val to DestType. /// Emit a cast from scalar value Val to DestType.
ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType, ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType,
QualType DestType); QualType DestType, SourceLocation Loc);
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Visitor Methods // Visitor Methods
@ -394,7 +394,8 @@ ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
/// Emit a cast from complex value Val to DestType. /// Emit a cast from complex value Val to DestType.
ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val, ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
QualType SrcType, QualType SrcType,
QualType DestType) { QualType DestType,
SourceLocation Loc) {
// Get the src/dest element type. // Get the src/dest element type.
SrcType = SrcType->castAs<ComplexType>()->getElementType(); SrcType = SrcType->castAs<ComplexType>()->getElementType();
DestType = DestType->castAs<ComplexType>()->getElementType(); DestType = DestType->castAs<ComplexType>()->getElementType();
@ -402,17 +403,18 @@ ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
// C99 6.3.1.6: When a value of complex type is converted to another // C99 6.3.1.6: When a value of complex type is converted to another
// complex type, both the real and imaginary parts follow the conversion // complex type, both the real and imaginary parts follow the conversion
// rules for the corresponding real types. // rules for the corresponding real types.
Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType); Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType, Loc);
Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType); Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType, Loc);
return Val; return Val;
} }
ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val, ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
QualType SrcType, QualType SrcType,
QualType DestType) { QualType DestType,
SourceLocation Loc) {
// Convert the input element to the element type of the complex. // Convert the input element to the element type of the complex.
DestType = DestType->castAs<ComplexType>()->getElementType(); DestType = DestType->castAs<ComplexType>()->getElementType();
Val = CGF.EmitScalarConversion(Val, SrcType, DestType); Val = CGF.EmitScalarConversion(Val, SrcType, DestType, Loc);
// Return (realval, 0). // Return (realval, 0).
return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType())); return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
@ -488,14 +490,15 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
case CK_FloatingRealToComplex: case CK_FloatingRealToComplex:
case CK_IntegralRealToComplex: case CK_IntegralRealToComplex:
return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op), return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op), Op->getType(),
Op->getType(), DestTy); DestTy, Op->getExprLoc());
case CK_FloatingComplexCast: case CK_FloatingComplexCast:
case CK_FloatingComplexToIntegralComplex: case CK_FloatingComplexToIntegralComplex:
case CK_IntegralComplexCast: case CK_IntegralComplexCast:
case CK_IntegralComplexToFloatingComplex: case CK_IntegralComplexToFloatingComplex:
return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy); return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy,
Op->getExprLoc());
} }
llvm_unreachable("unknown cast resulting in complex value"); llvm_unreachable("unknown cast resulting in complex value");
@ -846,19 +849,20 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
LValue LHS = CGF.EmitLValue(E->getLHS()); LValue LHS = CGF.EmitLValue(E->getLHS());
// Load from the l-value and convert it. // Load from the l-value and convert it.
SourceLocation Loc = E->getExprLoc();
if (LHSTy->isAnyComplexType()) { if (LHSTy->isAnyComplexType()) {
ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, E->getExprLoc()); ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, Loc);
OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty); OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
} else { } else {
llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, E->getExprLoc()); llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, Loc);
// For floating point real operands we can directly pass the scalar form // For floating point real operands we can directly pass the scalar form
// to the binary operator emission and potentially get more efficient code. // to the binary operator emission and potentially get more efficient code.
if (LHSTy->isRealFloatingType()) { if (LHSTy->isRealFloatingType()) {
if (!CGF.getContext().hasSameUnqualifiedType(ComplexElementTy, LHSTy)) if (!CGF.getContext().hasSameUnqualifiedType(ComplexElementTy, LHSTy))
LHSVal = CGF.EmitScalarConversion(LHSVal, LHSTy, ComplexElementTy); LHSVal = CGF.EmitScalarConversion(LHSVal, LHSTy, ComplexElementTy, Loc);
OpInfo.LHS = ComplexPairTy(LHSVal, nullptr); OpInfo.LHS = ComplexPairTy(LHSVal, nullptr);
} else { } else {
OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty); OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
} }
} }
@ -867,12 +871,13 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
// Truncate the result and store it into the LHS lvalue. // Truncate the result and store it into the LHS lvalue.
if (LHSTy->isAnyComplexType()) { if (LHSTy->isAnyComplexType()) {
ComplexPairTy ResVal = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy); ComplexPairTy ResVal =
EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy, Loc);
EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false); EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false);
Val = RValue::getComplex(ResVal); Val = RValue::getComplex(ResVal);
} else { } else {
llvm::Value *ResVal = llvm::Value *ResVal =
CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy); CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy, Loc);
CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false); CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false);
Val = RValue::get(ResVal); Val = RValue::get(ResVal);
} }

View File

@ -143,17 +143,19 @@ public:
/// Emit a check that a conversion to or from a floating-point type does not /// Emit a check that a conversion to or from a floating-point type does not
/// overflow. /// overflow.
void EmitFloatConversionCheck(Value *OrigSrc, QualType OrigSrcType, void EmitFloatConversionCheck(Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType, Value *Src, QualType SrcType, QualType DstType,
QualType DstType, llvm::Type *DstTy); llvm::Type *DstTy, SourceLocation Loc);
/// Emit a conversion from the specified type to the specified destination /// Emit a conversion from the specified type to the specified destination
/// type, both of which are LLVM scalar types. /// type, both of which are LLVM scalar types.
Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy); Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy,
SourceLocation Loc);
/// Emit a conversion from the specified complex type to the specified /// Emit a conversion from the specified complex type to the specified
/// destination type, where the destination type is an LLVM scalar type. /// destination type, where the destination type is an LLVM scalar type.
Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src, Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
QualType SrcTy, QualType DstTy); QualType SrcTy, QualType DstTy,
SourceLocation Loc);
/// EmitNullValue - Emit a value that corresponds to null for the given type. /// EmitNullValue - Emit a value that corresponds to null for the given type.
Value *EmitNullValue(QualType Ty); Value *EmitNullValue(QualType Ty);
@ -593,11 +595,9 @@ Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
return EmitPointerToBoolConversion(Src); return EmitPointerToBoolConversion(Src);
} }
void ScalarExprEmitter::EmitFloatConversionCheck(Value *OrigSrc, void ScalarExprEmitter::EmitFloatConversionCheck(
QualType OrigSrcType, Value *OrigSrc, QualType OrigSrcType, Value *Src, QualType SrcType,
Value *Src, QualType SrcType, QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
QualType DstType,
llvm::Type *DstTy) {
CodeGenFunction::SanitizerScope SanScope(&CGF); CodeGenFunction::SanitizerScope SanScope(&CGF);
using llvm::APFloat; using llvm::APFloat;
using llvm::APSInt; using llvm::APSInt;
@ -721,11 +721,9 @@ void ScalarExprEmitter::EmitFloatConversionCheck(Value *OrigSrc,
} }
} }
// FIXME: Provide a SourceLocation. llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc),
llvm::Constant *StaticArgs[] = { CGF.EmitCheckTypeDescriptor(OrigSrcType),
CGF.EmitCheckTypeDescriptor(OrigSrcType), CGF.EmitCheckTypeDescriptor(DstType)};
CGF.EmitCheckTypeDescriptor(DstType)
};
CGF.EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow), CGF.EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
"float_cast_overflow", StaticArgs, OrigSrc); "float_cast_overflow", StaticArgs, OrigSrc);
} }
@ -733,7 +731,8 @@ void ScalarExprEmitter::EmitFloatConversionCheck(Value *OrigSrc,
/// Emit a conversion from the specified type to the specified destination type, /// Emit a conversion from the specified type to the specified destination type,
/// both of which are LLVM scalar types. /// both of which are LLVM scalar types.
Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
QualType DstType) { QualType DstType,
SourceLocation Loc) {
SrcType = CGF.getContext().getCanonicalType(SrcType); SrcType = CGF.getContext().getCanonicalType(SrcType);
DstType = CGF.getContext().getCanonicalType(DstType); DstType = CGF.getContext().getCanonicalType(DstType);
if (SrcType == DstType) return Src; if (SrcType == DstType) return Src;
@ -808,7 +807,7 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
if (DstType->isExtVectorType() && !SrcType->isVectorType()) { if (DstType->isExtVectorType() && !SrcType->isVectorType()) {
// Cast the scalar to element type // Cast the scalar to element type
QualType EltTy = DstType->getAs<ExtVectorType>()->getElementType(); QualType EltTy = DstType->getAs<ExtVectorType>()->getElementType();
llvm::Value *Elt = EmitScalarConversion(Src, SrcType, EltTy); llvm::Value *Elt = EmitScalarConversion(Src, SrcType, EltTy, Loc);
// Splat the element across to all elements // Splat the element across to all elements
unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements(); unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
@ -828,8 +827,8 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
// or the destination type is a floating-point type. // or the destination type is a floating-point type.
if (CGF.SanOpts.has(SanitizerKind::FloatCastOverflow) && if (CGF.SanOpts.has(SanitizerKind::FloatCastOverflow) &&
(OrigSrcType->isFloatingType() || DstType->isFloatingType())) (OrigSrcType->isFloatingType() || DstType->isFloatingType()))
EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
DstTy); Loc);
// Cast to half through float if half isn't a native type. // Cast to half through float if half isn't a native type.
if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
@ -885,17 +884,17 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
/// Emit a conversion from the specified complex type to the specified /// Emit a conversion from the specified complex type to the specified
/// destination type, where the destination type is an LLVM scalar type. /// destination type, where the destination type is an LLVM scalar type.
Value *ScalarExprEmitter:: Value *ScalarExprEmitter::EmitComplexToScalarConversion(
EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src, CodeGenFunction::ComplexPairTy Src, QualType SrcTy, QualType DstTy,
QualType SrcTy, QualType DstTy) { SourceLocation Loc) {
// Get the source element type. // Get the source element type.
SrcTy = SrcTy->castAs<ComplexType>()->getElementType(); SrcTy = SrcTy->castAs<ComplexType>()->getElementType();
// Handle conversions to bool first, they are special: comparisons against 0. // Handle conversions to bool first, they are special: comparisons against 0.
if (DstTy->isBooleanType()) { if (DstTy->isBooleanType()) {
// Complex != 0 -> (Real != 0) | (Imag != 0) // Complex != 0 -> (Real != 0) | (Imag != 0)
Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy); Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy); Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
return Builder.CreateOr(Src.first, Src.second, "tobool"); return Builder.CreateOr(Src.first, Src.second, "tobool");
} }
@ -903,7 +902,7 @@ EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
// the imaginary part of the complex value is discarded and the value of the // the imaginary part of the complex value is discarded and the value of the
// real part is converted according to the conversion rules for the // real part is converted according to the conversion rules for the
// corresponding real type. // corresponding real type.
return EmitScalarConversion(Src.first, SrcTy, DstTy); return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
} }
Value *ScalarExprEmitter::EmitNullValue(QualType Ty) { Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
@ -1559,7 +1558,8 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
llvm::Type *DstTy = ConvertType(DestTy); llvm::Type *DstTy = ConvertType(DestTy);
Value *Elt = Visit(const_cast<Expr*>(E)); Value *Elt = Visit(const_cast<Expr*>(E));
Elt = EmitScalarConversion(Elt, E->getType(), Elt = EmitScalarConversion(Elt, E->getType(),
DestTy->getAs<VectorType>()->getElementType()); DestTy->getAs<VectorType>()->getElementType(),
CE->getExprLoc());
// Splat the element across to all elements // Splat the element across to all elements
unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements(); unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
@ -1570,7 +1570,8 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
case CK_IntegralToFloating: case CK_IntegralToFloating:
case CK_FloatingToIntegral: case CK_FloatingToIntegral:
case CK_FloatingCast: case CK_FloatingCast:
return EmitScalarConversion(Visit(E), E->getType(), DestTy); return EmitScalarConversion(Visit(E), E->getType(), DestTy,
CE->getExprLoc());
case CK_IntegralToBoolean: case CK_IntegralToBoolean:
return EmitIntToBoolConversion(Visit(E)); return EmitIntToBoolConversion(Visit(E));
case CK_PointerToBoolean: case CK_PointerToBoolean:
@ -1592,7 +1593,8 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
CodeGenFunction::ComplexPairTy V = CGF.EmitComplexExpr(E); CodeGenFunction::ComplexPairTy V = CGF.EmitComplexExpr(E);
// TODO: kill this function off, inline appropriate case here // TODO: kill this function off, inline appropriate case here
return EmitComplexToScalarConversion(V, E->getType(), DestTy); return EmitComplexToScalarConversion(V, E->getType(), DestTy,
CE->getExprLoc());
} }
case CK_ZeroToOCLEvent: { case CK_ZeroToOCLEvent: {
@ -2168,8 +2170,10 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue(
llvm_unreachable("Invalid compound assignment type"); llvm_unreachable("Invalid compound assignment type");
} }
if (aop != llvm::AtomicRMWInst::BAD_BINOP) { if (aop != llvm::AtomicRMWInst::BAD_BINOP) {
llvm::Value *amt = CGF.EmitToMemory(EmitScalarConversion(OpInfo.RHS, llvm::Value *amt = CGF.EmitToMemory(
E->getRHS()->getType(), LHSTy), LHSTy); EmitScalarConversion(OpInfo.RHS, E->getRHS()->getType(), LHSTy,
E->getExprLoc()),
LHSTy);
Builder.CreateAtomicRMW(aop, LHSLV.getAddress(), amt, Builder.CreateAtomicRMW(aop, LHSLV.getAddress(), amt,
llvm::SequentiallyConsistent); llvm::SequentiallyConsistent);
return LHSLV; return LHSLV;
@ -2190,14 +2194,16 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue(
else else
OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc()); OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());
OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, SourceLocation Loc = E->getExprLoc();
E->getComputationLHSType()); OpInfo.LHS =
EmitScalarConversion(OpInfo.LHS, LHSTy, E->getComputationLHSType(), Loc);
// Expand the binary operator. // Expand the binary operator.
Result = (this->*Func)(OpInfo); Result = (this->*Func)(OpInfo);
// Convert the result back to the LHS type. // Convert the result back to the LHS type.
Result = EmitScalarConversion(Result, E->getComputationResultType(), LHSTy); Result =
EmitScalarConversion(Result, E->getComputationResultType(), LHSTy, Loc);
if (atomicPHI) { if (atomicPHI) {
llvm::BasicBlock *opBB = Builder.GetInsertBlock(); llvm::BasicBlock *opBB = Builder.GetInsertBlock();
@ -2921,7 +2927,8 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc,
Value *CR6Param = Builder.getInt32(CR6); Value *CR6Param = Builder.getInt32(CR6);
llvm::Function *F = CGF.CGM.getIntrinsic(ID); llvm::Function *F = CGF.CGM.getIntrinsic(ID);
Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg}); Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType()); return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
E->getExprLoc());
} }
if (LHS->getType()->isFPOrFPVectorTy()) { if (LHS->getType()->isFPOrFPVectorTy()) {
@ -2990,7 +2997,8 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc,
} }
} }
return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType()); return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
E->getExprLoc());
} }
Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) { Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
@ -3472,21 +3480,23 @@ Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) {
/// Emit a conversion from the specified type to the specified destination type, /// Emit a conversion from the specified type to the specified destination type,
/// both of which are LLVM scalar types. /// both of which are LLVM scalar types.
Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy, Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy,
QualType DstTy) { QualType DstTy,
SourceLocation Loc) {
assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) && assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) &&
"Invalid scalar expression to emit"); "Invalid scalar expression to emit");
return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy); return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
} }
/// Emit a conversion from the specified complex type to the specified /// Emit a conversion from the specified complex type to the specified
/// destination type, where the destination type is an LLVM scalar type. /// destination type, where the destination type is an LLVM scalar type.
Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src, Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src,
QualType SrcTy, QualType SrcTy,
QualType DstTy) { QualType DstTy,
SourceLocation Loc) {
assert(SrcTy->isAnyComplexType() && hasScalarEvaluationKind(DstTy) && assert(SrcTy->isAnyComplexType() && hasScalarEvaluationKind(DstTy) &&
"Invalid complex -> scalar conversion"); "Invalid complex -> scalar conversion");
return ScalarExprEmitter(*this).EmitComplexToScalarConversion(Src, SrcTy, return ScalarExprEmitter(*this)
DstTy); .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
} }

View File

@ -1284,12 +1284,12 @@ void CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF,
} }
static void emitIfStmt(CodeGenFunction &CGF, llvm::Value *IfCond, static void emitIfStmt(CodeGenFunction &CGF, llvm::Value *IfCond,
OpenMPDirectiveKind Kind, OpenMPDirectiveKind Kind, SourceLocation Loc,
const RegionCodeGenTy &BodyOpGen) { const RegionCodeGenTy &BodyOpGen) {
llvm::Value *CallBool = CGF.EmitScalarConversion( llvm::Value *CallBool = CGF.EmitScalarConversion(
IfCond, IfCond,
CGF.getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true), CGF.getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true),
CGF.getContext().BoolTy); CGF.getContext().BoolTy, Loc);
auto *ThenBlock = CGF.createBasicBlock("omp_if.then"); auto *ThenBlock = CGF.createBasicBlock("omp_if.then");
auto *ContBlock = CGF.createBasicBlock("omp_if.end"); auto *ContBlock = CGF.createBasicBlock("omp_if.end");
@ -1315,13 +1315,14 @@ void CGOpenMPRuntime::emitMasterRegion(CodeGenFunction &CGF,
CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_master), Args); CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_master), Args);
typedef CallEndCleanup<std::extent<decltype(Args)>::value> typedef CallEndCleanup<std::extent<decltype(Args)>::value>
MasterCallEndCleanup; MasterCallEndCleanup;
emitIfStmt(CGF, IsMaster, OMPD_master, [&](CodeGenFunction &CGF) -> void { emitIfStmt(
CodeGenFunction::RunCleanupsScope Scope(CGF); CGF, IsMaster, OMPD_master, Loc, [&](CodeGenFunction &CGF) -> void {
CGF.EHStack.pushCleanup<MasterCallEndCleanup>( CodeGenFunction::RunCleanupsScope Scope(CGF);
NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_master), CGF.EHStack.pushCleanup<MasterCallEndCleanup>(
llvm::makeArrayRef(Args)); NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_master),
MasterOpGen(CGF); llvm::makeArrayRef(Args));
}); MasterOpGen(CGF);
});
} }
void CGOpenMPRuntime::emitTaskyieldCall(CodeGenFunction &CGF, void CGOpenMPRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
@ -1444,18 +1445,19 @@ void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF,
CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_single), Args); CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_single), Args);
typedef CallEndCleanup<std::extent<decltype(Args)>::value> typedef CallEndCleanup<std::extent<decltype(Args)>::value>
SingleCallEndCleanup; SingleCallEndCleanup;
emitIfStmt(CGF, IsSingle, OMPD_single, [&](CodeGenFunction &CGF) -> void { emitIfStmt(
CodeGenFunction::RunCleanupsScope Scope(CGF); CGF, IsSingle, OMPD_single, Loc, [&](CodeGenFunction &CGF) -> void {
CGF.EHStack.pushCleanup<SingleCallEndCleanup>( CodeGenFunction::RunCleanupsScope Scope(CGF);
NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_single), CGF.EHStack.pushCleanup<SingleCallEndCleanup>(
llvm::makeArrayRef(Args)); NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_single),
SingleOpGen(CGF); llvm::makeArrayRef(Args));
if (DidIt) { SingleOpGen(CGF);
// did_it = 1; if (DidIt) {
CGF.Builder.CreateAlignedStore(CGF.Builder.getInt32(1), DidIt, // did_it = 1;
DidIt->getAlignment()); CGF.Builder.CreateAlignedStore(CGF.Builder.getInt32(1), DidIt,
} DidIt->getAlignment());
}); }
});
// call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>, // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
// <copy_func>, did_it); // <copy_func>, did_it);
if (DidIt) { if (DidIt) {
@ -1719,7 +1721,7 @@ llvm::Value *CGOpenMPRuntime::emitForNext(CodeGenFunction &CGF,
CGF.EmitRuntimeCall(createDispatchNextFunction(IVSize, IVSigned), Args); CGF.EmitRuntimeCall(createDispatchNextFunction(IVSize, IVSigned), Args);
return CGF.EmitScalarConversion( return CGF.EmitScalarConversion(
Call, CGF.getContext().getIntTypeForBitwidth(32, /* Signed */ true), Call, CGF.getContext().getIntTypeForBitwidth(32, /* Signed */ true),
CGF.getContext().BoolTy); CGF.getContext().BoolTy, Loc);
} }
void CGOpenMPRuntime::emitNumThreadsClause(CodeGenFunction &CGF, void CGOpenMPRuntime::emitNumThreadsClause(CodeGenFunction &CGF,

View File

@ -1065,7 +1065,8 @@ emitScheduleClause(CodeGenFunction &CGF, const OMPLoopDirective &S,
if (!C->getHelperChunkSize() || !OuterRegion) { if (!C->getHelperChunkSize() || !OuterRegion) {
Chunk = CGF.EmitScalarExpr(Ch); Chunk = CGF.EmitScalarExpr(Ch);
Chunk = CGF.EmitScalarConversion(Chunk, Ch->getType(), Chunk = CGF.EmitScalarConversion(Chunk, Ch->getType(),
S.getIterationVariable()->getType()); S.getIterationVariable()->getType(),
S.getLocStart());
} }
} }
} }
@ -1683,27 +1684,29 @@ void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {
} }
static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val, static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val,
QualType SrcType, QualType DestType) { QualType SrcType, QualType DestType,
SourceLocation Loc) {
assert(CGF.hasScalarEvaluationKind(DestType) && assert(CGF.hasScalarEvaluationKind(DestType) &&
"DestType must have scalar evaluation kind."); "DestType must have scalar evaluation kind.");
assert(!Val.isAggregate() && "Must be a scalar or complex."); assert(!Val.isAggregate() && "Must be a scalar or complex.");
return Val.isScalar() return Val.isScalar()
? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, DestType) ? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, DestType,
Loc)
: CGF.EmitComplexToScalarConversion(Val.getComplexVal(), SrcType, : CGF.EmitComplexToScalarConversion(Val.getComplexVal(), SrcType,
DestType); DestType, Loc);
} }
static CodeGenFunction::ComplexPairTy static CodeGenFunction::ComplexPairTy
convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType,
QualType DestType) { QualType DestType, SourceLocation Loc) {
assert(CGF.getEvaluationKind(DestType) == TEK_Complex && assert(CGF.getEvaluationKind(DestType) == TEK_Complex &&
"DestType must have complex evaluation kind."); "DestType must have complex evaluation kind.");
CodeGenFunction::ComplexPairTy ComplexVal; CodeGenFunction::ComplexPairTy ComplexVal;
if (Val.isScalar()) { if (Val.isScalar()) {
// Convert the input element to the element type of the complex. // Convert the input element to the element type of the complex.
auto DestElementType = DestType->castAs<ComplexType>()->getElementType(); auto DestElementType = DestType->castAs<ComplexType>()->getElementType();
auto ScalarVal = auto ScalarVal = CGF.EmitScalarConversion(Val.getScalarVal(), SrcType,
CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, DestElementType); DestElementType, Loc);
ComplexVal = CodeGenFunction::ComplexPairTy( ComplexVal = CodeGenFunction::ComplexPairTy(
ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType())); ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
} else { } else {
@ -1711,9 +1714,9 @@ convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType,
auto SrcElementType = SrcType->castAs<ComplexType>()->getElementType(); auto SrcElementType = SrcType->castAs<ComplexType>()->getElementType();
auto DestElementType = DestType->castAs<ComplexType>()->getElementType(); auto DestElementType = DestType->castAs<ComplexType>()->getElementType();
ComplexVal.first = CGF.EmitScalarConversion( ComplexVal.first = CGF.EmitScalarConversion(
Val.getComplexVal().first, SrcElementType, DestElementType); Val.getComplexVal().first, SrcElementType, DestElementType, Loc);
ComplexVal.second = CGF.EmitScalarConversion( ComplexVal.second = CGF.EmitScalarConversion(
Val.getComplexVal().second, SrcElementType, DestElementType); Val.getComplexVal().second, SrcElementType, DestElementType, Loc);
} }
return ComplexVal; return ComplexVal;
} }
@ -1730,16 +1733,16 @@ static void emitSimpleAtomicStore(CodeGenFunction &CGF, bool IsSeqCst,
} }
static void emitSimpleStore(CodeGenFunction &CGF, LValue LVal, RValue RVal, static void emitSimpleStore(CodeGenFunction &CGF, LValue LVal, RValue RVal,
QualType RValTy) { QualType RValTy, SourceLocation Loc) {
switch (CGF.getEvaluationKind(LVal.getType())) { switch (CGF.getEvaluationKind(LVal.getType())) {
case TEK_Scalar: case TEK_Scalar:
CGF.EmitStoreThroughLValue( CGF.EmitStoreThroughLValue(RValue::get(convertToScalarValue(
RValue::get(convertToScalarValue(CGF, RVal, RValTy, LVal.getType())), CGF, RVal, RValTy, LVal.getType(), Loc)),
LVal); LVal);
break; break;
case TEK_Complex: case TEK_Complex:
CGF.EmitStoreOfComplex( CGF.EmitStoreOfComplex(
convertToComplexValue(CGF, RVal, RValTy, LVal.getType()), LVal, convertToComplexValue(CGF, RVal, RValTy, LVal.getType(), Loc), LVal,
/*isInit=*/false); /*isInit=*/false);
break; break;
case TEK_Aggregate: case TEK_Aggregate:
@ -1767,7 +1770,7 @@ static void EmitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst,
// list. // list.
if (IsSeqCst) if (IsSeqCst)
CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc); CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
emitSimpleStore(CGF,VLValue, Res, X->getType().getNonReferenceType()); emitSimpleStore(CGF, VLValue, Res, X->getType().getNonReferenceType(), Loc);
} }
static void EmitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst, static void EmitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst,
@ -1938,12 +1941,14 @@ static void EmitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst,
} }
static RValue convertToType(CodeGenFunction &CGF, RValue Value, static RValue convertToType(CodeGenFunction &CGF, RValue Value,
QualType SourceType, QualType ResType) { QualType SourceType, QualType ResType,
SourceLocation Loc) {
switch (CGF.getEvaluationKind(ResType)) { switch (CGF.getEvaluationKind(ResType)) {
case TEK_Scalar: case TEK_Scalar:
return RValue::get(convertToScalarValue(CGF, Value, SourceType, ResType)); return RValue::get(
convertToScalarValue(CGF, Value, SourceType, ResType, Loc));
case TEK_Complex: { case TEK_Complex: {
auto Res = convertToComplexValue(CGF, Value, SourceType, ResType); auto Res = convertToComplexValue(CGF, Value, SourceType, ResType, Loc);
return RValue::getComplex(Res.first, Res.second); return RValue::getComplex(Res.first, Res.second);
} }
case TEK_Aggregate: case TEK_Aggregate:
@ -2008,7 +2013,7 @@ static void EmitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst,
// 'x' is simply rewritten with some 'expr'. // 'x' is simply rewritten with some 'expr'.
NewVValType = X->getType().getNonReferenceType(); NewVValType = X->getType().getNonReferenceType();
ExprRValue = convertToType(CGF, ExprRValue, E->getType(), ExprRValue = convertToType(CGF, ExprRValue, E->getType(),
X->getType().getNonReferenceType()); X->getType().getNonReferenceType(), Loc);
auto &&Gen = [&CGF, &NewVVal, ExprRValue](RValue XRValue) -> RValue { auto &&Gen = [&CGF, &NewVVal, ExprRValue](RValue XRValue) -> RValue {
NewVVal = XRValue; NewVVal = XRValue;
return ExprRValue; return ExprRValue;
@ -2023,7 +2028,7 @@ static void EmitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst,
} }
} }
// Emit post-update store to 'v' of old/new 'x' value. // Emit post-update store to 'v' of old/new 'x' value.
emitSimpleStore(CGF, VLValue, NewVVal, NewVValType); emitSimpleStore(CGF, VLValue, NewVVal, NewVValType, Loc);
// OpenMP, 2.12.6, atomic Construct // OpenMP, 2.12.6, atomic Construct
// Any atomic construct with a seq_cst clause forces the atomically // Any atomic construct with a seq_cst clause forces the atomically
// performed operation to include an implicit flush operation without a // performed operation to include an implicit flush operation without a

View File

@ -2710,13 +2710,13 @@ public:
/// Emit a conversion from the specified type to the specified destination /// Emit a conversion from the specified type to the specified destination
/// type, both of which are LLVM scalar types. /// type, both of which are LLVM scalar types.
llvm::Value *EmitScalarConversion(llvm::Value *Src, QualType SrcTy, llvm::Value *EmitScalarConversion(llvm::Value *Src, QualType SrcTy,
QualType DstTy); QualType DstTy, SourceLocation Loc);
/// Emit a conversion from the specified complex type to the specified /// Emit a conversion from the specified complex type to the specified
/// destination type, where the destination type is an LLVM scalar type. /// destination type, where the destination type is an LLVM scalar type.
llvm::Value *EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, llvm::Value *EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy,
QualType DstTy); QualType DstTy,
SourceLocation Loc);
/// EmitAggExpr - Emit the computation of the specified expression /// EmitAggExpr - Emit the computation of the specified expression
/// of aggregate type. The result is computed into the given slot, /// of aggregate type. The result is computed into the given slot,

View File

@ -19,6 +19,17 @@
// CHECK-UBSAN: @[[LINE_700:.*]] = {{.*}}, i32 700, i32 14 {{.*}} @[[STRUCT_S]], i64 4, i8 3 } // CHECK-UBSAN: @[[LINE_700:.*]] = {{.*}}, i32 700, i32 14 {{.*}} @[[STRUCT_S]], i64 4, i8 3 }
// CHECK-UBSAN: @[[LINE_800:.*]] = {{.*}}, i32 800, i32 12 {{.*}} @{{.*}} } // CHECK-UBSAN: @[[LINE_800:.*]] = {{.*}}, i32 800, i32 12 {{.*}} @{{.*}} }
// CHECK-UBSAN: @[[LINE_900:.*]] = {{.*}}, i32 900, i32 11 {{.*}} @{{.*}} } // CHECK-UBSAN: @[[LINE_900:.*]] = {{.*}}, i32 900, i32 11 {{.*}} @{{.*}} }
// CHECK-UBSAN: @[[LINE_1000:.*]] = {{.*}}, i32 1000, i32 10 {{.*}} @{{.*}} }
// CHECK-UBSAN: @[[FP16:.*]] = private unnamed_addr constant { i16, i16, [9 x i8] } { i16 1, i16 16, [9 x i8] c"'__fp16'\00" }
// CHECK-UBSAN: @[[LINE_1100:.*]] = {{.*}}, i32 1100, i32 8 {{.*}} @{{.*}} }
// CHECK-UBSAN: @[[LINE_1200:.*]] = {{.*}}, i32 1200, i32 10 {{.*}} @{{.*}} }
// CHECK-UBSAN: @[[LINE_1300:.*]] = {{.*}}, i32 1300, i32 10 {{.*}} @{{.*}} }
// CHECK-UBSAN: @[[LINE_1400:.*]] = {{.*}}, i32 1400, i32 10 {{.*}} @{{.*}} }
// Make sure we check the fp16 type_mismatch data so we can easily match the signed char float_cast_overflow
// CHECK-UBSAN: @[[LINE_1500:.*]] = {{.*}}, i32 1500, i32 10 {{.*}} @[[FP16]], {{.*}} }
// CHECK-UBSAN: @[[SCHAR:.*]] = private unnamed_addr constant { i16, i16, [14 x i8] } { i16 0, i16 7, [14 x i8] c"'signed char'\00" }
// CHECK-UBSAN: @[[LINE_1500:.*]] = {{.*}}, i32 1500, i32 10 {{.*}} @[[FP16]], {{.*}} }
// CHECK-UBSAN: @[[LINE_1600:.*]] = {{.*}}, i32 1600, i32 10 {{.*}} @{{.*}} }
// CHECK-NULL: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} // CHECK-NULL: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}}
@ -209,10 +220,11 @@ float int_float_overflow(unsigned __int128 n) {
// CHECK-COMMON: %[[INBOUNDS:.*]] = icmp ule i128 %{{.*}}, -20282409603651670423947251286016 // CHECK-COMMON: %[[INBOUNDS:.*]] = icmp ule i128 %{{.*}}, -20282409603651670423947251286016
// CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]] // CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]]
// CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow( // CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1000]] to i8*),
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]] // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable // CHECK-TRAP-NEXT: unreachable
#line 1000
return n; return n;
} }
@ -223,10 +235,11 @@ void int_fp16_overflow(int n, __fp16 *p) {
// CHECK-COMMON: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]] // CHECK-COMMON: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
// CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]] // CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]]
// CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow( // CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1100]] to i8*),
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]] // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable // CHECK-TRAP-NEXT: unreachable
#line 1100
*p = n; *p = n;
} }
@ -239,10 +252,11 @@ int float_int_overflow(float f) {
// CHECK-UBSAN: %[[CAST:.*]] = bitcast float %[[F]] to i32 // CHECK-UBSAN: %[[CAST:.*]] = bitcast float %[[F]] to i32
// CHECK-UBSAN: %[[ARG:.*]] = zext i32 %[[CAST]] to i64 // CHECK-UBSAN: %[[ARG:.*]] = zext i32 %[[CAST]] to i64
// CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]] // CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1200]] to i8*), i64 %[[ARG]]
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]] // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable // CHECK-TRAP-NEXT: unreachable
#line 1200
return f; return f;
} }
@ -257,10 +271,11 @@ int long_double_int_overflow(long double ld) {
// CHECK-UBSAN: store x86_fp80 %[[F]], x86_fp80* %[[ALLOCA:.*]], !nosanitize // CHECK-UBSAN: store x86_fp80 %[[F]], x86_fp80* %[[ALLOCA:.*]], !nosanitize
// CHECK-UBSAN: %[[ARG:.*]] = ptrtoint x86_fp80* %[[ALLOCA]] to i64 // CHECK-UBSAN: %[[ARG:.*]] = ptrtoint x86_fp80* %[[ALLOCA]] to i64
// CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]] // CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1300]] to i8*), i64 %[[ARG]]
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]] // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable // CHECK-TRAP-NEXT: unreachable
#line 1300
return ld; return ld;
} }
@ -271,10 +286,11 @@ unsigned float_uint_overflow(float f) {
// CHECK-COMMON: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]] // CHECK-COMMON: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
// CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]] // CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]]
// CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow( // CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1400]] to i8*),
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]] // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable // CHECK-TRAP-NEXT: unreachable
#line 1400
return f; return f;
} }
@ -285,10 +301,11 @@ signed char fp16_char_overflow(__fp16 *p) {
// CHECK-COMMON: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]] // CHECK-COMMON: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
// CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]] // CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]]
// CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow( // CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1500]] to i8*),
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]] // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable // CHECK-TRAP-NEXT: unreachable
#line 1500
return *p; return *p;
} }
@ -301,10 +318,11 @@ float float_float_overflow(double f) {
// CHECK-COMMON: %[[INBOUNDS:.*]] = xor i1 %[[OUTOFBOUNDS]], true // CHECK-COMMON: %[[INBOUNDS:.*]] = xor i1 %[[OUTOFBOUNDS]], true
// CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]] // CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]]
// CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow( // CHECK-UBSAN: call void @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1600]] to i8*),
// CHECK-TRAP: call void @llvm.trap() [[NR_NUW]] // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable // CHECK-TRAP-NEXT: unreachable
#line 1600
return f; return f;
} }