mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
240 lines
6.0 KiB
Swift
240 lines
6.0 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %gyb %s -o %t/FixedPointArithmeticTraps.swift
|
|
// RUN: %line-directive %t/FixedPointArithmeticTraps.swift -- %target-build-swift %t/FixedPointArithmeticTraps.swift -o %t/a.out_Debug -Onone
|
|
// RUN: %line-directive %t/FixedPointArithmeticTraps.swift -- %target-build-swift %t/FixedPointArithmeticTraps.swift -o %t/a.out_Release -O
|
|
// RUN: %target-codesign %t/a.out_Debug
|
|
// RUN: %target-codesign %t/a.out_Release
|
|
//
|
|
// RUN: %line-directive %t/FixedPointArithmeticTraps.swift -- %target-run %t/a.out_Debug
|
|
// RUN: %line-directive %t/FixedPointArithmeticTraps.swift -- %target-run %t/a.out_Release
|
|
// REQUIRES: executable_test
|
|
|
|
import StdlibUnittest
|
|
|
|
|
|
// Note: in this file, we need to go through opaque functions to load
|
|
// constants. This is to check runtime behavior and ensure the constant is
|
|
// not folded.
|
|
|
|
func expectOverflow<T>(
|
|
_ res: (partialValue: T, overflow: Bool),
|
|
//===--- TRACE boilerplate ----------------------------------------------===//
|
|
_ message: @autoclosure () -> 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: (partialValue: T, overflow: Bool),
|
|
//===--- TRACE boilerplate ----------------------------------------------===//
|
|
_ message: @autoclosure () -> 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 all_integer_types
|
|
|
|
# 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 += 1
|
|
|
|
x = get${IntTy}(${IntTy}.min)
|
|
expectCrashLater()
|
|
// IntTy.min -= 1
|
|
x -= 1
|
|
_blackHole(x)
|
|
}
|
|
|
|
FixedPointArithmeticTraps.test("PreIncrement/${IntTy}") {
|
|
var x = get${IntTy}(${IntTy}.max)
|
|
x -= 1
|
|
|
|
x = get${IntTy}(${IntTy}.max)
|
|
expectCrashLater()
|
|
// IntTy.max += 1
|
|
x += 1
|
|
_blackHole(x)
|
|
}
|
|
|
|
FixedPointArithmeticTraps.test("PostDecrement/${IntTy}") {
|
|
var x = get${IntTy}(${IntTy}.min)
|
|
x += 1
|
|
|
|
x = get${IntTy}(${IntTy}.min)
|
|
expectCrashLater()
|
|
// IntTy.min -= 1
|
|
x -= 1
|
|
_blackHole(x)
|
|
}
|
|
|
|
FixedPointArithmeticTraps.test("PostIncrement/${IntTy}") {
|
|
var x = get${IntTy}(${IntTy}.max)
|
|
x -= 1
|
|
|
|
x = get${IntTy}(${IntTy}.max)
|
|
expectCrashLater()
|
|
// IntTy.max += 1
|
|
x += 1
|
|
_blackHole(x)
|
|
}
|
|
|
|
//
|
|
// Test addition for ${IntTy}
|
|
//
|
|
|
|
FixedPointArithmeticTraps.test("Addition/${IntTy}") {
|
|
var a = get${IntTy}(${IntTy}.max / 3)
|
|
|
|
expectNoOverflow(a.addingReportingOverflow(get${IntTy}(${IntTy}.max / 3)))
|
|
a = a + get${IntTy}(${IntTy}.max / 3)
|
|
|
|
expectNoOverflow(a.addingReportingOverflow(get${IntTy}(${IntTy}.max / 3)))
|
|
a = a + get${IntTy}(${IntTy}.max / 3)
|
|
|
|
// Overflow in addition.
|
|
expectOverflow(a.addingReportingOverflow(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(a.subtractingReportingOverflow(get${IntTy}(${IntTy}.max / 3)))
|
|
a = a - get${IntTy}(${IntTy}.max / 3)
|
|
|
|
// Overflow in subtraction.
|
|
expectOverflow(a.subtractingReportingOverflow(get${IntTy}(${IntTy}.max / 3)))
|
|
expectCrashLater()
|
|
a = a - get${IntTy}(${IntTy}.max / 3)
|
|
_blackHole(a)
|
|
}
|
|
|
|
//
|
|
// Test multiplication for ${IntTy}
|
|
//
|
|
|
|
FixedPointArithmeticTraps.test("Multiplication/${IntTy}") {
|
|
var a = get${IntTy}(${IntTy}.max / 3)
|
|
|
|
expectNoOverflow(a.multipliedReportingOverflow(by: get${IntTy}(2)))
|
|
a = a * get${IntTy}(2)
|
|
|
|
// Overflow in multiplication.
|
|
expectOverflow(a.multipliedReportingOverflow(by: 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(a.dividedReportingOverflow(by: get${IntTy}(3)))
|
|
a = a / get${IntTy}(3)
|
|
|
|
// x / 0
|
|
expectOverflow(a.dividedReportingOverflow(by: 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(a.dividedReportingOverflow(by: get${IntTy}(3)))
|
|
a = a / get${IntTy}(3)
|
|
|
|
a = get${IntTy}(${IntTy}.min)
|
|
expectOverflow(a.dividedReportingOverflow(by: 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(a.remainderReportingOverflow(dividingBy: get${IntTy}(3)))
|
|
a = a % get${IntTy}(3)
|
|
|
|
// x % 0
|
|
expectOverflow(a.remainderReportingOverflow(dividingBy: 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(a.remainderReportingOverflow(dividingBy: get${IntTy}(3)))
|
|
a = a % get${IntTy}(3)
|
|
|
|
// Int.min % -1
|
|
a = get${IntTy}(${IntTy}.min)
|
|
expectOverflow(a.remainderReportingOverflow(dividingBy: get${IntTy}(-1)))
|
|
expectCrashLater()
|
|
a = a % get${IntTy}(-1)
|
|
_blackHole(a)
|
|
}
|
|
|
|
% end
|
|
|
|
// This comment prevents gyb from miscompiling this file.
|
|
// <rdar://problem/17548877> gyb miscompiles a certain for loop
|
|
|
|
% end
|
|
|
|
runAllTests()
|
|
|