// RUN: rm -rf %t // RUN: mkdir -p %t // RUN: %S/../../utils/gyb %s -o %t/FixedPointArithmeticTraps.swift // RUN: %target-build-swift %t/FixedPointArithmeticTraps.swift -o %t/a.out_Debug // RUN: %target-build-swift %t/FixedPointArithmeticTraps.swift -o %t/a.out_Release -O // // RUN: %target-run %t/a.out_Debug // RUN: %target-run %t/a.out_Release import StdlibUnittest // 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( res: (T, overflow: Bool), file: String = __FILE__, line: UWord = __LINE__ ) { expectTrue( res.overflow, stackTrace: SourceLoc(file, line).withCurrentLoc()) { "expected overflow" } } func expectNoOverflow( res: (T, overflow: Bool), file: String = __FILE__, line: UWord = __LINE__ ) { expectFalse( res.overflow, stackTrace: SourceLoc(file, line).withCurrentLoc()) { "expected no overflow" } } %{ allIntTypes = [ ('signed', 'Int'), ('signed', 'Int8'), ('signed', 'Int16'), ('signed', 'Int32'), ('signed', 'Int64'), ('unsigned', 'UInt'), ('unsigned', 'UInt8'), ('unsigned', 'UInt16'), ('unsigned', 'UInt32'), ('unsigned', 'UInt64'), ] }% var FixedPointArithmeticTraps = TestSuite("FixedPointArithmeticTraps") % for (signedness, IntTy) in allIntTypes: // // 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 } FixedPointArithmeticTraps.test("PreIncrement/${IntTy}") { var x = get${IntTy}(${IntTy}.max) --x x = get${IntTy}(${IntTy}.max) expectCrashLater() // ++IntTy.max ++x } FixedPointArithmeticTraps.test("PostDecrement/${IntTy}") { var x = get${IntTy}(${IntTy}.min) x++ x = get${IntTy}(${IntTy}.min) expectCrashLater() // IntTy.min-- x-- } FixedPointArithmeticTraps.test("PostIncrement/${IntTy}") { var x = get${IntTy}(${IntTy}.max) x-- x = get${IntTy}(${IntTy}.max) expectCrashLater() // IntTy.max++ 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) } // // 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) } // // 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) } // // 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 signedness == '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 } % 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) } % if signedness == '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) } % end // This comment prevents gyb from miscompiling this file. // gyb miscompiles a certain for loop % end runAllTests()