r365272 - Treat the range of representable values of floating-point types as [-inf, +inf] not as [-max, +max].
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Sat Jul 6 14:05:52 PDT 2019
Author: rsmith
Date: Sat Jul 6 14:05:52 2019
New Revision: 365272
URL: http://llvm.org/viewvc/llvm-project?rev=365272&view=rev
Log:
Treat the range of representable values of floating-point types as [-inf, +inf] not as [-max, +max].
Summary:
Prior to r329065, we used [-max, max] as the range of representable
values because LLVM's `fptrunc` did not guarantee defined behavior when
truncating from a larger floating-point type to a smaller one. Now that
has been fixed, we can make clang follow normal IEEE 754 semantics in this
regard and take the larger range [-inf, +inf] as the range of representable
values.
In practice, this affects two parts of the frontend:
* the constant evaluator no longer treats floating-point evaluations
that result in +-inf as being undefined (because they no longer leave
the range of representable values of the type)
* UBSan no longer treats conversions to floating-point type that are
outside the [-max, +max] range as being undefined
In passing, also remove the float-divide-by-zero sanitizer from
-fsanitize=undefined, on the basis that while it's undefined per C++
rules (and we disallow it in constant expressions for that reason), it
is defined by Clang / LLVM / IEEE 754.
Reviewers: rnk, BillyONeal
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D63793
Modified:
cfe/trunk/docs/UndefinedBehaviorSanitizer.rst
cfe/trunk/include/clang/Basic/Sanitizers.def
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
cfe/trunk/test/CodeGen/catch-undef-behavior.c
cfe/trunk/test/Driver/fsanitize.c
cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp
Modified: cfe/trunk/docs/UndefinedBehaviorSanitizer.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UndefinedBehaviorSanitizer.rst?rev=365272&r1=365271&r2=365272&view=diff
==============================================================================
--- cfe/trunk/docs/UndefinedBehaviorSanitizer.rst (original)
+++ cfe/trunk/docs/UndefinedBehaviorSanitizer.rst Sat Jul 6 14:05:52 2019
@@ -83,9 +83,13 @@ Available checks are:
type.
- ``-fsanitize=float-cast-overflow``: Conversion to, from, or
between floating-point types which would overflow the
- destination.
+ destination. Because the range of representable values for all
+ floating-point types supported by Clang is [-inf, +inf], the only
+ cases detected are conversions from floating point to integer types.
- ``-fsanitize=float-divide-by-zero``: Floating point division by
- zero.
+ zero. This is undefined per the C and C++ standards, but is defined
+ by Clang (and by ISO/IEC/IEEE 60559 / IEEE 754) as producing either an
+ infinity or NaN value, so is not included in ``-fsanitize=undefined``.
- ``-fsanitize=function``: Indirect call of a function through a
function pointer of the wrong type (Darwin/Linux, C++ and x86/x86_64
only).
@@ -163,8 +167,8 @@ Available checks are:
You can also use the following check groups:
- ``-fsanitize=undefined``: All of the checks listed above other than
- ``unsigned-integer-overflow``, ``implicit-conversion`` and the
- ``nullability-*`` group of checks.
+ ``float-divide-by-zero``, ``unsigned-integer-overflow``,
+ ``implicit-conversion``, and the ``nullability-*`` group of checks.
- ``-fsanitize=undefined-trap``: Deprecated alias of
``-fsanitize=undefined``.
- ``-fsanitize=implicit-integer-truncation``: Catches lossy integral
@@ -174,16 +178,16 @@ You can also use the following check gro
conversions that change the arithmetic value of the integer. Enables
``implicit-signed-integer-truncation`` and ``implicit-integer-sign-change``.
- ``-fsanitize=implicit-conversion``: Checks for suspicious
- behaviour of implicit conversions. Enables
+ behavior of implicit conversions. Enables
``implicit-unsigned-integer-truncation``,
- ``implicit-signed-integer-truncation`` and
+ ``implicit-signed-integer-truncation``, and
``implicit-integer-sign-change``.
- ``-fsanitize=integer``: Checks for undefined or suspicious integer
behavior (e.g. unsigned integer overflow).
Enables ``signed-integer-overflow``, ``unsigned-integer-overflow``,
``shift``, ``integer-divide-by-zero``,
``implicit-unsigned-integer-truncation``,
- ``implicit-signed-integer-truncation`` and
+ ``implicit-signed-integer-truncation``, and
``implicit-integer-sign-change``.
- ``-fsanitize=nullability``: Enables ``nullability-arg``,
``nullability-assign``, and ``nullability-return``. While violating
Modified: cfe/trunk/include/clang/Basic/Sanitizers.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Sanitizers.def?rev=365272&r1=365271&r2=365272&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Sanitizers.def (original)
+++ cfe/trunk/include/clang/Basic/Sanitizers.def Sat Jul 6 14:05:52 2019
@@ -130,7 +130,7 @@ SANITIZER("shadow-call-stack", ShadowCal
// ABI or address space layout implications, and only catch undefined behavior.
SANITIZER_GROUP("undefined", Undefined,
Alignment | Bool | Builtin | ArrayBounds | Enum |
- FloatCastOverflow | FloatDivideByZero |
+ FloatCastOverflow |
IntegerDivideByZero | NonnullAttribute | Null | ObjectSize |
PointerOverflow | Return | ReturnsNonnullAttribute | Shift |
SignedIntegerOverflow | Unreachable | VLABound | Function |
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=365272&r1=365271&r2=365272&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sat Jul 6 14:05:52 2019
@@ -2212,10 +2212,8 @@ static bool HandleFloatToFloatCast(EvalI
APFloat &Result) {
APFloat Value = Result;
bool ignored;
- if (Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
- APFloat::rmNearestTiesToEven, &ignored)
- & APFloat::opOverflow)
- return HandleOverflow(Info, E, Value, DestType);
+ Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
+ APFloat::rmNearestTiesToEven, &ignored);
return true;
}
@@ -2236,10 +2234,8 @@ static bool HandleIntToFloatCast(EvalInf
QualType SrcType, const APSInt &Value,
QualType DestType, APFloat &Result) {
Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
- if (Result.convertFromAPInt(Value, Value.isSigned(),
- APFloat::rmNearestTiesToEven)
- & APFloat::opOverflow)
- return HandleOverflow(Info, E, Value, DestType);
+ Result.convertFromAPInt(Value, Value.isSigned(),
+ APFloat::rmNearestTiesToEven);
return true;
}
@@ -2457,11 +2453,19 @@ static bool handleFloatFloatBinOp(EvalIn
LHS.subtract(RHS, APFloat::rmNearestTiesToEven);
break;
case BO_Div:
+ // [expr.mul]p4:
+ // If the second operand of / or % is zero the behavior is undefined.
+ if (RHS.isZero())
+ Info.CCEDiag(E, diag::note_expr_divide_by_zero);
LHS.divide(RHS, APFloat::rmNearestTiesToEven);
break;
}
- if (LHS.isInfinity() || LHS.isNaN()) {
+ // [expr.pre]p4:
+ // If during the evaluation of an expression, the result is not
+ // mathematically defined [...], the behavior is undefined.
+ // FIXME: C++ rules require us to not conform to IEEE 754 here.
+ if (LHS.isNaN()) {
Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
return Info.noteUndefinedBehavior();
}
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=365272&r1=365271&r2=365272&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Sat Jul 6 14:05:52 2019
@@ -313,7 +313,7 @@ public:
/// boolean (i1) truth value. This is equivalent to "Val != 0".
Value *EmitConversionToBool(Value *Src, QualType DstTy);
- /// Emit a check that a conversion to or from a floating-point type does not
+ /// Emit a check that a conversion from a floating-point type does not
/// overflow.
void EmitFloatConversionCheck(Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType, QualType DstType,
@@ -864,128 +864,63 @@ Value *ScalarExprEmitter::EmitConversion
void ScalarExprEmitter::EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType, Value *Src, QualType SrcType,
QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
+ assert(SrcType->isFloatingType() && "not a conversion from floating point");
+ if (!isa<llvm::IntegerType>(DstTy))
+ return;
+
CodeGenFunction::SanitizerScope SanScope(&CGF);
using llvm::APFloat;
using llvm::APSInt;
- llvm::Type *SrcTy = Src->getType();
-
llvm::Value *Check = nullptr;
- if (llvm::IntegerType *IntTy = dyn_cast<llvm::IntegerType>(SrcTy)) {
- // Integer to floating-point. This can fail for unsigned short -> __half
- // or unsigned __int128 -> float.
- assert(DstType->isFloatingType());
- bool SrcIsUnsigned = OrigSrcType->isUnsignedIntegerOrEnumerationType();
-
- APFloat LargestFloat =
- APFloat::getLargest(CGF.getContext().getFloatTypeSemantics(DstType));
- APSInt LargestInt(IntTy->getBitWidth(), SrcIsUnsigned);
-
- bool IsExact;
- if (LargestFloat.convertToInteger(LargestInt, APFloat::rmTowardZero,
- &IsExact) != APFloat::opOK)
- // The range of representable values of this floating point type includes
- // all values of this integer type. Don't need an overflow check.
- return;
-
- llvm::Value *Max = llvm::ConstantInt::get(VMContext, LargestInt);
- if (SrcIsUnsigned)
- Check = Builder.CreateICmpULE(Src, Max);
- else {
- llvm::Value *Min = llvm::ConstantInt::get(VMContext, -LargestInt);
- llvm::Value *GE = Builder.CreateICmpSGE(Src, Min);
- llvm::Value *LE = Builder.CreateICmpSLE(Src, Max);
- Check = Builder.CreateAnd(GE, LE);
- }
- } else {
- const llvm::fltSemantics &SrcSema =
- CGF.getContext().getFloatTypeSemantics(OrigSrcType);
- if (isa<llvm::IntegerType>(DstTy)) {
- // Floating-point to integer. This has undefined behavior if the source is
- // +-Inf, NaN, or doesn't fit into the destination type (after truncation
- // to an integer).
- unsigned Width = CGF.getContext().getIntWidth(DstType);
- bool Unsigned = DstType->isUnsignedIntegerOrEnumerationType();
-
- APSInt Min = APSInt::getMinValue(Width, Unsigned);
- APFloat MinSrc(SrcSema, APFloat::uninitialized);
- if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) &
- APFloat::opOverflow)
- // Don't need an overflow check for lower bound. Just check for
- // -Inf/NaN.
- MinSrc = APFloat::getInf(SrcSema, true);
- else
- // Find the largest value which is too small to represent (before
- // truncation toward zero).
- MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative);
-
- APSInt Max = APSInt::getMaxValue(Width, Unsigned);
- APFloat MaxSrc(SrcSema, APFloat::uninitialized);
- if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) &
- APFloat::opOverflow)
- // Don't need an overflow check for upper bound. Just check for
- // +Inf/NaN.
- MaxSrc = APFloat::getInf(SrcSema, false);
- else
- // Find the smallest value which is too large to represent (before
- // truncation toward zero).
- MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive);
-
- // If we're converting from __half, convert the range to float to match
- // the type of src.
- if (OrigSrcType->isHalfType()) {
- const llvm::fltSemantics &Sema =
- CGF.getContext().getFloatTypeSemantics(SrcType);
- bool IsInexact;
- MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
- MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
- }
+ const llvm::fltSemantics &SrcSema =
+ CGF.getContext().getFloatTypeSemantics(OrigSrcType);
- llvm::Value *GE =
- Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
- llvm::Value *LE =
- Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
- Check = Builder.CreateAnd(GE, LE);
- } else {
- // FIXME: Maybe split this sanitizer out from float-cast-overflow.
- //
- // Floating-point to floating-point. This has undefined behavior if the
- // source is not in the range of representable values of the destination
- // type. The C and C++ standards are spectacularly unclear here. We
- // diagnose finite out-of-range conversions, but allow infinities and NaNs
- // to convert to the corresponding value in the smaller type.
- //
- // C11 Annex F gives all such conversions defined behavior for IEC 60559
- // conforming implementations. Unfortunately, LLVM's fptrunc instruction
- // does not.
-
- // Converting from a lower rank to a higher rank can never have
- // undefined behavior, since higher-rank types must have a superset
- // of values of lower-rank types.
- if (CGF.getContext().getFloatingTypeOrder(OrigSrcType, DstType) != 1)
- return;
-
- assert(!OrigSrcType->isHalfType() &&
- "should not check conversion from __half, it has the lowest rank");
-
- const llvm::fltSemantics &DstSema =
- CGF.getContext().getFloatTypeSemantics(DstType);
- APFloat MinBad = APFloat::getLargest(DstSema, false);
- APFloat MaxBad = APFloat::getInf(DstSema, false);
-
- bool IsInexact;
- MinBad.convert(SrcSema, APFloat::rmTowardZero, &IsInexact);
- MaxBad.convert(SrcSema, APFloat::rmTowardZero, &IsInexact);
-
- Value *AbsSrc = CGF.EmitNounwindRuntimeCall(
- CGF.CGM.getIntrinsic(llvm::Intrinsic::fabs, Src->getType()), Src);
- llvm::Value *GE =
- Builder.CreateFCmpOGT(AbsSrc, llvm::ConstantFP::get(VMContext, MinBad));
- llvm::Value *LE =
- Builder.CreateFCmpOLT(AbsSrc, llvm::ConstantFP::get(VMContext, MaxBad));
- Check = Builder.CreateNot(Builder.CreateAnd(GE, LE));
- }
- }
+ // Floating-point to integer. This has undefined behavior if the source is
+ // +-Inf, NaN, or doesn't fit into the destination type (after truncation
+ // to an integer).
+ unsigned Width = CGF.getContext().getIntWidth(DstType);
+ bool Unsigned = DstType->isUnsignedIntegerOrEnumerationType();
+
+ APSInt Min = APSInt::getMinValue(Width, Unsigned);
+ APFloat MinSrc(SrcSema, APFloat::uninitialized);
+ if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) &
+ APFloat::opOverflow)
+ // Don't need an overflow check for lower bound. Just check for
+ // -Inf/NaN.
+ MinSrc = APFloat::getInf(SrcSema, true);
+ else
+ // Find the largest value which is too small to represent (before
+ // truncation toward zero).
+ MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative);
+
+ APSInt Max = APSInt::getMaxValue(Width, Unsigned);
+ APFloat MaxSrc(SrcSema, APFloat::uninitialized);
+ if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) &
+ APFloat::opOverflow)
+ // Don't need an overflow check for upper bound. Just check for
+ // +Inf/NaN.
+ MaxSrc = APFloat::getInf(SrcSema, false);
+ else
+ // Find the smallest value which is too large to represent (before
+ // truncation toward zero).
+ MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive);
+
+ // If we're converting from __half, convert the range to float to match
+ // the type of src.
+ if (OrigSrcType->isHalfType()) {
+ const llvm::fltSemantics &Sema =
+ CGF.getContext().getFloatTypeSemantics(SrcType);
+ bool IsInexact;
+ MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
+ MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
+ }
+
+ llvm::Value *GE =
+ Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
+ llvm::Value *LE =
+ Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
+ Check = Builder.CreateAnd(GE, LE);
llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc),
CGF.EmitCheckTypeDescriptor(OrigSrcType),
@@ -1391,9 +1326,12 @@ Value *ScalarExprEmitter::EmitScalarConv
llvm::Type *ResTy = DstTy;
// An overflowing conversion has undefined behavior if either the source type
- // or the destination type is a floating-point type.
+ // or the destination type is a floating-point type. However, we consider the
+ // range of representable values for all floating-point types to be
+ // [-inf,+inf], so no overflow can ever happen when the destination type is a
+ // floating-point type.
if (CGF.SanOpts.has(SanitizerKind::FloatCastOverflow) &&
- (OrigSrcType->isFloatingType() || DstType->isFloatingType()))
+ OrigSrcType->isFloatingType())
EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
Loc);
Modified: cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp?rev=365272&r1=365271&r2=365272&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp Sat Jul 6 14:05:52 2019
@@ -136,9 +136,9 @@ namespace UndefinedBehavior {
case (int)10000000000ll: // expected-note {{here}}
case (unsigned int)10000000000ll: // expected-error {{duplicate case value}}
case (int)(unsigned)(long long)4.4e9: // ok
- case (int)(float)1e300: // expected-error {{constant expression}} expected-note {{value 1.0E+300 is outside the range of representable values of type 'float'}}
+ case (int)(float)1e300: // expected-error {{constant expression}} expected-note {{value +Inf is outside the range of representable values of type 'int'}}
case (int)((float)1e37 / 1e30): // ok
- case (int)(__fp16)65536: // expected-error {{constant expression}} expected-note {{value 65536 is outside the range of representable values of type '__fp16'}}
+ case (int)(__fp16)65536: // expected-error {{constant expression}} expected-note {{value +Inf is outside the range of representable values of type 'int'}}
break;
}
}
@@ -264,14 +264,28 @@ namespace UndefinedBehavior {
static_assert(0u - 1u == 4294967295u, ""); // ok
static_assert(~0u * ~0u == 1u, ""); // ok
+ template<typename T> constexpr bool isinf(T v) { return v && v / 2 == v; }
+
// Floating-point overflow and NaN.
constexpr float f1 = 1e38f * 3.4028f; // ok
- constexpr float f2 = 1e38f * 3.4029f; // expected-error {{constant expression}} expected-note {{floating point arithmetic produces an infinity}}
+ constexpr float f2 = 1e38f * 3.4029f; // ok, +inf is in range of representable values
constexpr float f3 = 1e38f / -.2939f; // ok
- constexpr float f4 = 1e38f / -.2938f; // expected-error {{constant expression}} expected-note {{floating point arithmetic produces an infinity}}
- constexpr float f5 = 2e38f + 2e38f; // expected-error {{constant expression}} expected-note {{floating point arithmetic produces an infinity}}
- constexpr float f6 = -2e38f - 2e38f; // expected-error {{constant expression}} expected-note {{floating point arithmetic produces an infinity}}
- constexpr float f7 = 0.f / 0.f; // expected-error {{constant expression}} expected-note {{floating point arithmetic produces a NaN}}
+ constexpr float f4 = 1e38f / -.2938f; // ok, -inf is in range of representable values
+ constexpr float f5 = 2e38f + 2e38f; // ok, +inf is in range of representable values
+ constexpr float f6 = -2e38f - 2e38f; // ok, -inf is in range of representable values
+ constexpr float f7 = 0.f / 0.f; // expected-error {{constant expression}} expected-note {{division by zero}}
+ constexpr float f8 = 1.f / 0.f; // expected-error {{constant expression}} expected-note {{division by zero}}
+ constexpr float f9 = 1e308 / 1e-308; // ok, +inf
+ constexpr float f10 = f2 - f2; // expected-error {{constant expression}} expected-note {{produces a NaN}}
+ constexpr float f11 = f2 + f4; // expected-error {{constant expression}} expected-note {{produces a NaN}}
+ constexpr float f12 = f2 / f2; // expected-error {{constant expression}} expected-note {{produces a NaN}}
+ static_assert(!isinf(f1), "");
+ static_assert(isinf(f2), "");
+ static_assert(!isinf(f3), "");
+ static_assert(isinf(f4), "");
+ static_assert(isinf(f5), "");
+ static_assert(isinf(f6), "");
+ static_assert(isinf(f9), "");
}
}
Modified: cfe/trunk/test/CodeGen/catch-undef-behavior.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/catch-undef-behavior.c?rev=365272&r1=365271&r2=365272&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/catch-undef-behavior.c (original)
+++ cfe/trunk/test/CodeGen/catch-undef-behavior.c Sat Jul 6 14:05:52 2019
@@ -17,9 +17,7 @@
// CHECK-UBSAN: @[[LINE_700:.*]] = {{.*}}, i32 700, i32 14 {{.*}} @[[STRUCT_S]], i8 2, i8 3 }
// CHECK-UBSAN: @[[LINE_800:.*]] = {{.*}}, i32 800, i32 12 {{.*}} @{{.*}} }
// 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 {{.*}} @{{.*}} }
@@ -27,7 +25,6 @@
// 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 {{.*}} @{{.*}} }
// PR6805
// CHECK-COMMON-LABEL: @foo
@@ -197,30 +194,16 @@ float int_float_no_overflow(__int128 n)
// CHECK-COMMON-LABEL: @int_float_overflow
float int_float_overflow(unsigned __int128 n) {
- // This is 2**104. FLT_MAX is 2**128 - 2**104.
- // CHECK-COMMON: %[[INBOUNDS:.*]] = icmp ule i128 %{{.*}}, -20282409603651670423947251286016
- // CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]]
-
- // 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-NEXT: unreachable
-#line 1000
+ // CHECK-UBSAN-NOT: call {{.*}} @__ubsan_handle_float_cast_overflow(
+ // CHECK-TRAP-NOT: call {{.*}} @llvm.trap(
+ // CHECK-COMMON: }
return n;
}
// CHECK-COMMON-LABEL: @int_fp16_overflow
void int_fp16_overflow(int n, __fp16 *p) {
- // CHECK-COMMON: %[[GE:.*]] = icmp sge i32 %{{.*}}, -65504
- // CHECK-COMMON: %[[LE:.*]] = icmp sle i32 %{{.*}}, 65504
- // CHECK-COMMON: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
- // CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]]
-
- // 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-NEXT: unreachable
-#line 1100
+ // CHECK-UBSAN-NOT: call {{.*}} @__ubsan_handle_float_cast_overflow(
+ // CHECK-COMMON: }
*p = n;
}
@@ -292,18 +275,9 @@ signed char fp16_char_overflow(__fp16 *p
// CHECK-COMMON-LABEL: @float_float_overflow
float float_float_overflow(double f) {
- // CHECK-COMMON: %[[F:.*]] = call double @llvm.fabs.f64(
- // CHECK-COMMON: %[[GE:.*]] = fcmp ogt double %[[F]], 0x47EFFFFFE0000000
- // CHECK-COMMON: %[[LE:.*]] = fcmp olt double %[[F]], 0x7FF0000000000000
- // CHECK-COMMON: %[[OUTOFBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
- // CHECK-COMMON: %[[INBOUNDS:.*]] = xor i1 %[[OUTOFBOUNDS]], true
- // CHECK-COMMON-NEXT: br i1 %[[INBOUNDS]]
-
- // 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-NEXT: unreachable
-#line 1600
+ // CHECK-UBSAN-NOT: call {{.*}} @__ubsan_handle_float_cast_overflow(i8* bitcast ({{.*}} @[[LINE_1600]] to i8*),
+ // CHECK-TRAP-NOT: call {{.*}} @llvm.trap() [[NR_NUW]]
+ // CHECK-COMMON: }
return f;
}
Modified: cfe/trunk/test/Driver/fsanitize.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/fsanitize.c?rev=365272&r1=365271&r2=365272&view=diff
==============================================================================
--- cfe/trunk/test/Driver/fsanitize.c (original)
+++ cfe/trunk/test/Driver/fsanitize.c Sat Jul 6 14:05:52 2019
@@ -4,15 +4,15 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
// RUN: %clang -target x86_64-linux-gnu -fsanitize-undefined-trap-on-error -fsanitize=undefined-trap %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
// CHECK-UNDEFINED-TRAP-NOT: -fsanitize-recover
-// CHECK-UNDEFINED-TRAP: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){19}"}}
-// CHECK-UNDEFINED-TRAP: "-fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,float-divide-by-zero,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound"
-// CHECK-UNDEFINED-TRAP2: "-fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,float-divide-by-zero,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,unreachable,vla-bound"
+// CHECK-UNDEFINED-TRAP: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){18}"}}
+// CHECK-UNDEFINED-TRAP: "-fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound"
+// CHECK-UNDEFINED-TRAP2: "-fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,unreachable,vla-bound"
// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED
-// CHECK-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){20}"}}
+// CHECK-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){19}"}}
// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-DARWIN
-// CHECK-UNDEFINED-DARWIN: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){19}"}}
+// CHECK-UNDEFINED-DARWIN: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}}
// RUN: %clang -target i386-pc-win32 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN32
// RUN: %clang -target i386-pc-win32 -fsanitize=undefined -x c++ %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN32 --check-prefix=CHECK-UNDEFINED-WIN-CXX
@@ -23,7 +23,7 @@
// CHECK-UNDEFINED-WIN64: "--dependent-lib={{[^"]*}}ubsan_standalone-x86_64.lib"
// CHECK-UNDEFINED-WIN64-MINGW: "--dependent-lib={{[^"]*}}libclang_rt.ubsan_standalone-x86_64.a"
// CHECK-UNDEFINED-WIN-CXX: "--dependent-lib={{[^"]*}}ubsan_standalone_cxx{{[^"]*}}.lib"
-// CHECK-UNDEFINED-WIN-SAME: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}}
+// CHECK-UNDEFINED-WIN-SAME: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){17}"}}
// RUN: %clang -target i386-pc-win32 -fsanitize-coverage=bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-COVERAGE-WIN32
// CHECK-COVERAGE-WIN32: "--dependent-lib={{[^"]*}}ubsan_standalone-i386.lib"
@@ -88,7 +88,7 @@
// CHECK-FNO-SANITIZE-ALL: "-fsanitize=thread"
// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread,undefined -fno-sanitize=thread -fno-sanitize=float-cast-overflow,vptr,bool,builtin,enum %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-UNDEFINED
-// CHECK-PARTIAL-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|array-bounds|returns-nonnull-attribute|nonnull-attribute),?){15}"}}
+// CHECK-PARTIAL-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|array-bounds|returns-nonnull-attribute|nonnull-attribute),?){14}"}}
// RUN: %clang -target x86_64-linux-gnu -fsanitize=shift -fno-sanitize=shift-base %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSANITIZE-SHIFT-PARTIAL
// CHECK-FSANITIZE-SHIFT-PARTIAL: "-fsanitize=shift-exponent"
@@ -339,7 +339,7 @@
// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover=undefined -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-UBSAN
// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover=all -fsanitize-recover=thread -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-UBSAN
// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fsanitize-recover=all -fno-sanitize-recover=undefined -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-UBSAN
-// CHECK-RECOVER-UBSAN: "-fsanitize-recover={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}}
+// CHECK-RECOVER-UBSAN: "-fsanitize-recover={{((signed-integer-overflow|integer-divide-by-zero|function|shift-base|shift-exponent|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){17}"}}
// CHECK-NO-RECOVER-UBSAN-NOT: sanitize-recover
// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover=all -fsanitize-recover=object-size,shift-base -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-RECOVER
@@ -749,7 +749,7 @@
// CHECK-TSAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=thread'
// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-MINIMAL
-// CHECK-UBSAN-MINIMAL: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){19}"}}
+// CHECK-UBSAN-MINIMAL: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){18}"}}
// CHECK-UBSAN-MINIMAL: "-fsanitize-minimal-runtime"
// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize=vptr -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-VPTR-MINIMAL
Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp?rev=365272&r1=365271&r2=365272&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp Sat Jul 6 14:05:52 2019
@@ -425,7 +425,7 @@ namespace compound_assign {
constexpr bool test_overflow() {
T a = 1;
while (a != a / 2)
- a *= 2; // expected-note {{value 2147483648 is outside the range}} expected-note {{ 9223372036854775808 }} expected-note {{floating point arithmetic produces an infinity}}
+ a *= 2; // expected-note {{value 2147483648 is outside the range}} expected-note {{ 9223372036854775808 }}
return true;
}
@@ -435,7 +435,8 @@ namespace compound_assign {
static_assert(test_overflow<unsigned short>(), ""); // ok
static_assert(test_overflow<unsigned long long>(), ""); // ok
static_assert(test_overflow<long long>(), ""); // expected-error {{constant}} expected-note {{call}}
- static_assert(test_overflow<float>(), ""); // expected-error {{constant}} expected-note {{call}}
+ static_assert(test_overflow<float>(), ""); // ok
+ static_assert(test_overflow<double>(), ""); // ok
constexpr short test_promotion(short k) {
short s = k;
More information about the cfe-commits
mailing list