mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
374 lines
9.2 KiB
Plaintext
374 lines
9.2 KiB
Plaintext
// RUN: rm -rf %t
|
|
// RUN: mkdir -p %t
|
|
// RUN: %S/../../utils/gyb %s -o %t/FixedPointArithmeticTraps.swift
|
|
// RUN: %S/../../utils/line-directive %t/FixedPointArithmeticTraps.swift -- %target-build-swift %t/FixedPointArithmeticTraps.swift -o %t/a.out_Debug
|
|
// RUN: %S/../../utils/line-directive %t/FixedPointArithmeticTraps.swift -- %target-build-swift %t/FixedPointArithmeticTraps.swift -o %t/a.out_Release -O
|
|
//
|
|
// RUN: %S/../../utils/line-directive %t/FixedPointArithmeticTraps.swift -- %target-run %t/a.out_Debug
|
|
// RUN: %S/../../utils/line-directive %t/FixedPointArithmeticTraps.swift -- %target-run %t/a.out_Release
|
|
// REQUIRES: executable_test
|
|
|
|
import StdlibUnittest
|
|
|
|
// Also import modules which are used by StdlibUnittest internally. This is
|
|
// needed to link all required libraries in case we serialize StdlibUnittest.
|
|
import SwiftPrivate
|
|
#if _runtime(_ObjC)
|
|
import ObjectiveC
|
|
#endif
|
|
|
|
// Note: in this file, we need to go through opaque functions to load
|
|
// constants. This is to to check runtime behaviour and ensure the constant is
|
|
// not folded.
|
|
|
|
func expectOverflow<T>(
|
|
res: (T, overflow: Bool),
|
|
//===--- TRACE boilerplate ----------------------------------------------===//
|
|
@autoclosure _ message: ()->String = "",
|
|
showFrame: Bool = true,
|
|
stackTrace: SourceLocStack = SourceLocStack(),
|
|
file: String = __FILE__, line: UInt = __LINE__
|
|
) {
|
|
expectTrue(
|
|
res.overflow, "expected overflow",
|
|
stackTrace: stackTrace.pushIf(showFrame, file: file, line: line))
|
|
}
|
|
|
|
func expectNoOverflow<T>(
|
|
res: (T, overflow: Bool),
|
|
//===--- TRACE boilerplate ----------------------------------------------===//
|
|
@autoclosure _ message: ()->String = "",
|
|
showFrame: Bool = true,
|
|
stackTrace: SourceLocStack = SourceLocStack(),
|
|
file: String = __FILE__, line: UInt = __LINE__
|
|
) {
|
|
expectFalse(
|
|
res.overflow, "expected no overflow",
|
|
stackTrace: stackTrace.pushIf(showFrame, file: file, line: line))
|
|
}
|
|
|
|
%{
|
|
|
|
from SwiftIntTypes import *
|
|
|
|
# Test cases are written in a way that they don't depend on the word size.
|
|
word_bits = 4
|
|
|
|
}%
|
|
|
|
var FixedPointArithmeticTraps = TestSuite("FixedPointArithmeticTraps")
|
|
|
|
% for self_ty in all_integer_types(word_bits):
|
|
% IntTy = self_ty.stdlib_name
|
|
|
|
//
|
|
// Test pre- and post-increment/decrement for ${IntTy}
|
|
//
|
|
|
|
FixedPointArithmeticTraps.test("PreDecrement/${IntTy}") {
|
|
var x = get${IntTy}(${IntTy}.min)
|
|
++x
|
|
|
|
x = get${IntTy}(${IntTy}.min)
|
|
expectCrashLater()
|
|
// --IntTy.min
|
|
--x
|
|
_blackHole(x)
|
|
}
|
|
|
|
FixedPointArithmeticTraps.test("PreIncrement/${IntTy}") {
|
|
var x = get${IntTy}(${IntTy}.max)
|
|
--x
|
|
|
|
x = get${IntTy}(${IntTy}.max)
|
|
expectCrashLater()
|
|
// ++IntTy.max
|
|
++x
|
|
_blackHole(x)
|
|
}
|
|
|
|
FixedPointArithmeticTraps.test("PostDecrement/${IntTy}") {
|
|
var x = get${IntTy}(${IntTy}.min)
|
|
x++
|
|
|
|
x = get${IntTy}(${IntTy}.min)
|
|
expectCrashLater()
|
|
// IntTy.min--
|
|
x--
|
|
_blackHole(x)
|
|
}
|
|
|
|
FixedPointArithmeticTraps.test("PostIncrement/${IntTy}") {
|
|
var x = get${IntTy}(${IntTy}.max)
|
|
x--
|
|
|
|
x = get${IntTy}(${IntTy}.max)
|
|
expectCrashLater()
|
|
// IntTy.max++
|
|
x++
|
|
_blackHole(x)
|
|
}
|
|
|
|
//
|
|
// Test addition for ${IntTy}
|
|
//
|
|
|
|
FixedPointArithmeticTraps.test("Addition/${IntTy}") {
|
|
var a = get${IntTy}(${IntTy}.max / 3)
|
|
|
|
expectNoOverflow(${IntTy}.addWithOverflow(a, get${IntTy}(${IntTy}.max / 3)))
|
|
a = a + get${IntTy}(${IntTy}.max / 3)
|
|
|
|
expectNoOverflow(${IntTy}.addWithOverflow(a, get${IntTy}(${IntTy}.max / 3)))
|
|
a = a + get${IntTy}(${IntTy}.max / 3)
|
|
|
|
// Overflow in addition.
|
|
expectOverflow(${IntTy}.addWithOverflow(a, get${IntTy}(${IntTy}.max / 3)))
|
|
expectCrashLater()
|
|
a = a + get${IntTy}(${IntTy}.max / 3)
|
|
_blackHole(a)
|
|
}
|
|
|
|
//
|
|
// Test subtraction for ${IntTy}
|
|
//
|
|
|
|
FixedPointArithmeticTraps.test("Subtraction/${IntTy}") {
|
|
var a = get${IntTy}(${IntTy}.min + get${IntTy}(${IntTy}.max / 3))
|
|
|
|
expectNoOverflow(${IntTy}.subtractWithOverflow(a, get${IntTy}(${IntTy}.max / 3)))
|
|
a = a - get${IntTy}(${IntTy}.max / 3)
|
|
|
|
// Overflow in subtraction.
|
|
expectOverflow(${IntTy}.subtractWithOverflow(a, get${IntTy}(${IntTy}.max / 3)))
|
|
expectCrashLater()
|
|
a = a - get${IntTy}(${IntTy}.max / 3)
|
|
_blackHole(a)
|
|
}
|
|
|
|
//
|
|
// Test multiplication for ${IntTy}
|
|
//
|
|
|
|
FixedPointArithmeticTraps.test("Multplication/${IntTy}") {
|
|
var a = get${IntTy}(${IntTy}.max / 3)
|
|
|
|
expectNoOverflow(${IntTy}.multiplyWithOverflow(a, get${IntTy}(2)))
|
|
a = a * get${IntTy}(2)
|
|
|
|
// Overflow in multiplication.
|
|
expectOverflow(${IntTy}.multiplyWithOverflow(a, get${IntTy}(2)))
|
|
expectCrashLater()
|
|
a = a * get${IntTy}(2)
|
|
_blackHole(a)
|
|
}
|
|
|
|
//
|
|
// Test division for ${IntTy}
|
|
//
|
|
|
|
FixedPointArithmeticTraps.test("Division/${IntTy}") {
|
|
var a = get${IntTy}(${IntTy}.max / 3)
|
|
|
|
// x / 3
|
|
expectNoOverflow(${IntTy}.divideWithOverflow(a, get${IntTy}(3)))
|
|
a = a / get${IntTy}(3)
|
|
|
|
// x / 0
|
|
expectOverflow(${IntTy}.divideWithOverflow(a, get${IntTy}(0)))
|
|
expectCrashLater()
|
|
a = a / get${IntTy}(0)
|
|
}
|
|
|
|
% if self_ty.is_signed:
|
|
|
|
FixedPointArithmeticTraps.test("Division/${IntTy}.min-over-minus-one") {
|
|
var a = get${IntTy}(${IntTy}.min)
|
|
|
|
expectNoOverflow(${IntTy}.divideWithOverflow(a, get${IntTy}(3)))
|
|
a = a / get${IntTy}(3)
|
|
|
|
a = get${IntTy}(${IntTy}.min)
|
|
expectOverflow(${IntTy}.divideWithOverflow(a, get${IntTy}(-1)))
|
|
expectCrashLater()
|
|
a = a / get${IntTy}(-1)
|
|
// IntTy.min / -1
|
|
_blackHole(a)
|
|
}
|
|
|
|
% end
|
|
|
|
//
|
|
// Test remainder computation for ${IntTy}
|
|
//
|
|
|
|
FixedPointArithmeticTraps.test("Remainder/${IntTy}") {
|
|
var a = get${IntTy}(${IntTy}.max / 3)
|
|
|
|
// x % 3
|
|
expectNoOverflow(${IntTy}.remainderWithOverflow(a, get${IntTy}(3)))
|
|
a = a % get${IntTy}(3)
|
|
|
|
// x % 0
|
|
expectOverflow(${IntTy}.remainderWithOverflow(a, get${IntTy}(0)))
|
|
expectCrashLater()
|
|
a = a % get${IntTy}(0)
|
|
_blackHole(a)
|
|
}
|
|
|
|
% if self_ty.is_signed:
|
|
|
|
FixedPointArithmeticTraps.test("Remainder/${IntTy}.min-mod-minus-one") {
|
|
var a = get${IntTy}(${IntTy}.min)
|
|
|
|
// Int.min % 3
|
|
expectNoOverflow(${IntTy}.remainderWithOverflow(a, get${IntTy}(3)))
|
|
a = a % get${IntTy}(3)
|
|
|
|
// Int.min % -1
|
|
a = get${IntTy}(${IntTy}.min)
|
|
expectOverflow(${IntTy}.remainderWithOverflow(a, get${IntTy}(-1)))
|
|
expectCrashLater()
|
|
a = a % get${IntTy}(-1)
|
|
_blackHole(a)
|
|
}
|
|
|
|
% end
|
|
|
|
% for (description, operation) in [("RightShift", ">>"), ("LeftShift", "<<")]:
|
|
|
|
//
|
|
// Test ${description} for ${IntTy}
|
|
//
|
|
|
|
% if self_ty.is_signed:
|
|
|
|
FixedPointArithmeticTraps.test("${description}/${IntTy}/Negative") {
|
|
var a = get${IntTy}(${IntTy}.max / 3)
|
|
|
|
a = get${IntTy}(a ${operation} get${IntTy}(1))
|
|
|
|
let shiftAmount: ${IntTy} = -1
|
|
|
|
// Overflow in ${description}.
|
|
expectCrashLater()
|
|
a = a ${operation} get${IntTy}(shiftAmount)
|
|
_blackHole(a)
|
|
}
|
|
|
|
% end
|
|
|
|
FixedPointArithmeticTraps.test("${description}/${IntTy}/TypeSize") {
|
|
var a = get${IntTy}(${IntTy}.max / 3)
|
|
|
|
a = get${IntTy}(a ${operation} get${IntTy}(0))
|
|
a = get${IntTy}(a ${operation} get${IntTy}(1))
|
|
|
|
let shiftAmount = ${IntTy}(sizeof(${IntTy}.self) * 8)
|
|
|
|
// Overflow in ${description}.
|
|
expectCrashLater()
|
|
a = a ${operation} get${IntTy}(shiftAmount)
|
|
_blackHole(a)
|
|
}
|
|
|
|
FixedPointArithmeticTraps.test("${description}/${IntTy}/TypeSizePlusOne") {
|
|
var a = get${IntTy}(${IntTy}.max / 3)
|
|
|
|
a = get${IntTy}(a ${operation} get${IntTy}(0))
|
|
|
|
let shiftAmount = ${IntTy}(sizeof(${IntTy}.self) * 8 + 1)
|
|
|
|
// Overflow in ${description}.
|
|
expectCrashLater()
|
|
a = a ${operation} get${IntTy}(shiftAmount)
|
|
_blackHole(a)
|
|
}
|
|
|
|
FixedPointArithmeticTraps.test("${description}/${IntTy}/Max") {
|
|
var a = get${IntTy}(${IntTy}.max / 3)
|
|
|
|
a = get${IntTy}(a ${operation} get${IntTy}(0))
|
|
|
|
let shiftAmount: ${IntTy} = ${IntTy}.max
|
|
|
|
// Overflow in ${description}.
|
|
expectCrashLater()
|
|
a = a ${operation} get${IntTy}(shiftAmount)
|
|
_blackHole(a)
|
|
}
|
|
|
|
% end
|
|
|
|
// This comment prevents gyb from miscompiling this file.
|
|
// <rdar://problem/17548877> gyb miscompiles a certain for loop
|
|
|
|
% end
|
|
|
|
// FIXME: these tests should be more thorough, and test all combinations of
|
|
// types and error conditions.
|
|
var FixedPointTruncationTraps = TestSuite("FixedPointTruncationTraps")
|
|
|
|
FixedPointTruncationTraps.test("SignedToSignedTruncation/dest=sign-overflow") {
|
|
// Test that we check if we overflow on the sign bit.
|
|
var x = getInt16(128)
|
|
expectCrashLater()
|
|
var result = Int8(x)
|
|
_blackHole(result)
|
|
}
|
|
|
|
FixedPointTruncationTraps.test("SignedToUnsignedTruncation/src=-1") {
|
|
var x = getInt32(-1)
|
|
expectCrashLater()
|
|
var result = UInt8(x)
|
|
_blackHole(result)
|
|
}
|
|
|
|
FixedPointTruncationTraps.test("SignedToUnignedSameSize/src=min") {
|
|
var x = getInt8(-128)
|
|
expectCrashLater()
|
|
var result = UInt16(x)
|
|
_blackHole(result)
|
|
}
|
|
|
|
|
|
FixedPointTruncationTraps.test("SignedToUnsignedTruncation/src=max") {
|
|
var x = getInt32(0xFFFFFFF)
|
|
expectCrashLater()
|
|
var result = UInt16(x)
|
|
_blackHole(result)
|
|
}
|
|
|
|
FixedPointTruncationTraps.test("UnsignedToSignedTruncation/dest=sign-overflow") {
|
|
// Test that we check if we overflow on the sign bit.
|
|
var x = getUInt16(128)
|
|
expectCrashLater()
|
|
var result = Int8(x)
|
|
_blackHole(result)
|
|
}
|
|
|
|
FixedPointTruncationTraps.test("UnsignedToUnsignedTruncation/src=max") {
|
|
var x = getUInt32(0xFFFFFFFF)
|
|
expectCrashLater()
|
|
var result = UInt16(x)
|
|
_blackHole(result)
|
|
}
|
|
|
|
// Same size conversions.
|
|
FixedPointTruncationTraps.test("SignedToUnsignedSameSize") {
|
|
var x = getInt8(-2)
|
|
expectCrashLater()
|
|
var result = UInt8(x)
|
|
_blackHole(result)
|
|
}
|
|
|
|
FixedPointTruncationTraps.test("UnsignedToSignedSameSize") {
|
|
var x = getUInt8(128)
|
|
expectCrashLater()
|
|
var result = Int8(x)
|
|
_blackHole(result)
|
|
}
|
|
|
|
runAllTests()
|
|
|