107 lines
3.5 KiB
Racket
107 lines
3.5 KiB
Racket
#lang racket/base
|
|
|
|
(require
|
|
rackunit
|
|
racket/sandbox
|
|
racket/flonum racket/fixnum racket/unsafe/ops
|
|
racket/math
|
|
syntax/srcloc
|
|
(for-syntax
|
|
racket/base
|
|
syntax/parse))
|
|
|
|
(provide tests)
|
|
|
|
|
|
(define (mk-eval lang)
|
|
(call-with-trusted-sandbox-configuration
|
|
(λ ()
|
|
(parameterize ([sandbox-memory-limit 300])
|
|
(make-evaluator lang)))))
|
|
(define racket-eval (mk-eval 'racket))
|
|
(define tr-eval (mk-eval 'typed/racket))
|
|
|
|
(define-syntax bad-opt
|
|
(syntax-parser
|
|
[(_ exp:expr)
|
|
#`(test-case #,(format "~a" (syntax->datum #'exp))
|
|
(define r-value (racket-eval #'exp))
|
|
(define tr-value (tr-eval #'exp))
|
|
(with-check-info (['r-value r-value]
|
|
['tr-value tr-value]
|
|
['location (build-source-location-list (quote-syntax exp))])
|
|
(when (equal? r-value tr-value)
|
|
(fail-check "Known bug no longer exists."))))]))
|
|
|
|
(define-syntax good-opt
|
|
(syntax-parser
|
|
[(_ exp:expr)
|
|
#`(test-case #,(format "~a" (syntax->datum #'exp))
|
|
(define r-value (racket-eval #'exp))
|
|
(define tr-value (tr-eval #'exp))
|
|
(with-check-info (['r-value r-value]
|
|
['tr-value tr-value]
|
|
['location (build-source-location-list (quote-syntax exp))])
|
|
(when (not (equal? r-value tr-value))
|
|
(fail-check "Optimizer regression"))))]))
|
|
|
|
|
|
;; TODO add this as a test
|
|
;; type-before = Single-Flonum-Complex
|
|
;; type-after = Float-Complex
|
|
;; redex-check: <collects>/typed-racket-test/tr-random-testing.rkt:258
|
|
;; counterexample found after 499 attempts:
|
|
;(log (make-rectangular -inf.f -inf.f))
|
|
|
|
(define tests
|
|
(test-suite "Known bugs"
|
|
|
|
;; Arguments are converted to inexact too early
|
|
(bad-opt (* (make-rectangular -inf.0 1) (* 1 1)))
|
|
(bad-opt (/ -inf.0-inf.0i 8))
|
|
(good-opt (- (* -1 1 +nan.0) 1.0+1.0i))
|
|
(good-opt (- (* (/ 6 11) (/ 1.2345678f0 123456.7f0)) (make-rectangular 0.0 0.3)))
|
|
(bad-opt (/ 1.0 0.0+0.0i))
|
|
(good-opt (+ 0.0+0.0i (* 1 1 +inf.0)))
|
|
(bad-opt (* 1.0f-30 1.0f-30 1.0e60+1.0e60i))
|
|
|
|
;; Unary division has bad underflow
|
|
(good-opt (/ (make-rectangular 1e+100 1e-300)))
|
|
(good-opt (/ 0.5+1.7e+308i))
|
|
(bad-opt (/ 1 (make-rectangular 1e+100 1e-300)))
|
|
(bad-opt (/ 1 0.5+1.7e+308i))
|
|
|
|
;; Division of complex 0 should only make part of the result nan
|
|
(good-opt (/ 0.0+0.0i))
|
|
(bad-opt (/ 1 0.0+0.0i))
|
|
(bad-opt (/ 1.5 -3.0+9.8e-324i))
|
|
|
|
;; Division of complex infinity should only make part of the result nan
|
|
(good-opt (/ (make-rectangular 1.0 +inf.0)))
|
|
(good-opt (/ (make-rectangular +inf.0 1.0)))
|
|
(bad-opt (/ 1 (make-rectangular 1.0 +inf.0)))
|
|
(bad-opt (/ 1 (make-rectangular +inf.0 1.0)))
|
|
|
|
;; Exp of large real should have 0 imaginary component
|
|
(good-opt (+ (exp 1.7976931348623151e+308) 0.0+0.0i))
|
|
|
|
;; Multiplication of multiple args should keep exact semantics for exact args
|
|
(bad-opt (* (expt 10 500) (expt 10 -500) 1.0+1.0i))
|
|
|
|
;; Addition of multiple args should keep exact semantics for exact args
|
|
(bad-opt (+ (expt 10 501) (expt -10 501) 1.0+1.0i))
|
|
|
|
;; Magnitude should not overflow unless necessary
|
|
(bad-opt (magnitude 3.0e300+4.0e300i))
|
|
|
|
;; Negation should correctly compute sign of 0.0
|
|
(good-opt (- 0.0+0.0i))
|
|
(bad-opt (- 0+0i 0.0+0.0i))
|
|
|
|
;; Conjugate should correctly compute sign of 0.0
|
|
(good-opt (conjugate 0.0+0.0i))))
|
|
|
|
(module+ main
|
|
(require rackunit/text-ui)
|
|
(void (run-tests tests)))
|