summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAndrea Corallo <akrl@sdf.org>2021-04-25 20:06:22 +0200
committerAndrea Corallo <akrl@sdf.org>2021-04-25 20:06:22 +0200
commit289000eee729689b0cf362a21baa40ac7f9506f6 (patch)
tree04e59d0f2bd7111749d8d97f829a410d4602a247 /test
parent8f63f0078a23421eada97b4da51b9308b82532ce (diff)
parentfa65c044f2ebe666467166075c1507a8d0e1347f (diff)
downloademacs-289000eee729689b0cf362a21baa40ac7f9506f6.tar.gz
Merge branch 'feature/native-comp' into into trunk
Diffstat (limited to 'test')
-rw-r--r--test/Makefile.in10
-rw-r--r--test/infra/gitlab-ci.yml32
-rw-r--r--test/lisp/auth-source-tests.el3
-rw-r--r--test/lisp/emacs-lisp/comp-cstr-tests.el229
-rw-r--r--test/lisp/help-fns-tests.el8
-rw-r--r--test/lisp/subr-tests.el2
-rw-r--r--test/src/comp-test-45603.el28
-rw-r--r--test/src/comp-test-funcs-dyn.el50
-rw-r--r--test/src/comp-test-funcs.el710
-rw-r--r--test/src/comp-test-pure.el40
-rw-r--r--test/src/comp-tests.el1446
11 files changed, 2554 insertions, 4 deletions
diff --git a/test/Makefile.in b/test/Makefile.in
index 91a8ea141c3..84ab4e70aee 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -47,6 +47,8 @@ SO = @MODULES_SUFFIX@
SEPCHAR = @SEPCHAR@
+HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@
+
-include ${top_builddir}/src/verbose.mk
# Load any GNU ELPA dependencies that are present, for optional tests.
@@ -118,6 +120,8 @@ emacs = LANG=C EMACSLOADPATH= \
# Set HOME to a nonexistent directory to prevent tests from accessing
# it accidentally (e.g., popping up a gnupg dialog if ~/.authinfo.gpg
# exists, or writing to ~/.bzr.log when running bzr commands).
+# NOTE if the '/nonexistent' name is changed `normal-top-level' in
+# startup.el must be updated too.
TEST_HOME = /nonexistent
test_module_dir := src/emacs-module-resources
@@ -126,9 +130,15 @@ test_module_dir := src/emacs-module-resources
all: check
+ifeq ($(HAVE_NATIVE_COMP),yes)
SELECTOR_DEFAULT = (not (or (tag :expensive-test) (tag :unstable)))
SELECTOR_EXPENSIVE = (not (tag :unstable))
SELECTOR_ALL = t
+else
+SELECTOR_DEFAULT = (not (or (tag :expensive-test) (tag :unstable) (tag :nativecomp)))
+SELECTOR_EXPENSIVE = (not (or (tag :unstable) (tag :nativecomp)))
+SELECTOR_ALL = (not (tag :nativecomp))
+endif
ifdef SELECTOR
SELECTOR_ACTUAL=$(SELECTOR)
else ifndef MAKECMDGOALS
diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml
index 6355513cc9f..b740f43402d 100644
--- a/test/infra/gitlab-ci.yml
+++ b/test/infra/gitlab-ci.yml
@@ -243,6 +243,38 @@ test-filenotify-gio:
target: emacs-filenotify-gio
make_params: "-k -C test autorevert-tests.log filenotify-tests.log"
+test-native-bootstrap-speed0:
+ # Test a full native bootstrap
+ # Run for now only speed 0 to limit memory usage and compilation time.
+ stage: slow
+ # Uncomment the following to run it only when sceduled.
+ # only:
+ # - schedules
+ script:
+ - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y -qq -o=Dpkg::Use-Pty=0 libgccjit-6-dev
+ - ./autogen.sh autoconf
+ - ./configure --without-makeinfo --with-nativecomp
+ - make bootstrap NATIVE_FULL_AOT=1 BYTE_COMPILE_EXTRA_FLAGS='--eval "(setq comp-speed 0)"' -j2
+ timeout: 8 hours
+
+test-native-bootstrap-speed1:
+ stage: slow
+ script:
+ - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y -qq -o=Dpkg::Use-Pty=0 libgccjit-6-dev
+ - ./autogen.sh autoconf
+ - ./configure --without-makeinfo --with-nativecomp
+ - make bootstrap BYTE_COMPILE_EXTRA_FLAGS='--eval "(setq comp-speed 1)"'
+ timeout: 8 hours
+
+test-native-bootstrap-speed2:
+ stage: slow
+ script:
+ - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y -qq -o=Dpkg::Use-Pty=0 libgccjit-6-dev
+ - ./autogen.sh autoconf
+ - ./configure --without-makeinfo --with-nativecomp
+ - make bootstrap
+ timeout: 8 hours
+
test-gnustep:
# This tests the GNUstep build process
stage: platforms
diff --git a/test/lisp/auth-source-tests.el b/test/lisp/auth-source-tests.el
index 4f0d9949af5..19216d3c24a 100644
--- a/test/lisp/auth-source-tests.el
+++ b/test/lisp/auth-source-tests.el
@@ -320,7 +320,8 @@
;; Redefine `read-*' in order to avoid interactive input.
(cl-letf (((symbol-function 'read-passwd) (lambda (_) passwd))
((symbol-function 'read-string)
- (lambda (_prompt _initial _history default) default)))
+ (lambda (_prompt _initial _history default _inherit-input-method)
+ default)))
(setq auth-info
(car (auth-source-search
:max 1 :host host :require '(:user :secret) :create t))))
diff --git a/test/lisp/emacs-lisp/comp-cstr-tests.el b/test/lisp/emacs-lisp/comp-cstr-tests.el
new file mode 100644
index 00000000000..c2492b93f6f
--- /dev/null
+++ b/test/lisp/emacs-lisp/comp-cstr-tests.el
@@ -0,0 +1,229 @@
+;;; comp-cstr-tests.el --- unit tests for src/comp.c -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Free Software Foundation, Inc.
+
+;; Author: Andrea Corallo <akrl@sdf.org>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Unit tests for lisp/emacs-lisp/comp-cstr.el
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+(require 'comp-cstr)
+
+(cl-eval-when (compile eval load)
+
+ (defun comp-cstr-test-ts (type-spec)
+ "Create a constraint from TYPE-SPEC and convert it back to type specifier."
+ (let ((comp-ctxt (make-comp-cstr-ctxt)))
+ (comp-cstr-to-type-spec (comp-type-spec-to-cstr type-spec))))
+
+ (defun comp-cstr-typespec-test (number type-spec expected-type-spec)
+ `(ert-deftest ,(intern (concat "comp-cstr-test-" (int-to-string number))) ()
+ (should (equal (comp-cstr-test-ts ',type-spec)
+ ',expected-type-spec))))
+
+ (defconst comp-cstr-typespec-tests-alist
+ `(;; 1
+ (symbol . symbol)
+ ;; 2
+ ((or string array) . array)
+ ;; 3
+ ((or symbol number) . (or number symbol))
+ ;; 4
+ ((or cons atom) . (or atom cons)) ;; SBCL return T
+ ;; 5
+ ((or integer number) . number)
+ ;; 6
+ ((or (or integer symbol) number) . (or number symbol))
+ ;; 7
+ ((or (or integer symbol) (or number list)) . (or list number symbol))
+ ;; 8
+ ((or (or integer number) nil) . number)
+ ;; 9
+ ((member foo) . (member foo))
+ ;; 10
+ ((member foo bar) . (member bar foo))
+ ;; 11
+ ((or (member foo) (member bar)) . (member bar foo))
+ ;; 12
+ ((or (member foo) symbol) . symbol) ;; SBCL return (OR SYMBOL (MEMBER FOO))
+ ;; 13
+ ((or (member foo) number) . (or (member foo) number))
+ ;; 14
+ ((or (integer 1 3) number) . number)
+ ;; 15
+ (integer . integer)
+ ;; 16
+ ((integer 1 2) . (integer 1 2))
+ ;; 17
+ ((or (integer -1 0) (integer 3 4)) . (or (integer -1 0) (integer 3 4)))
+ ;; 18
+ ((or (integer -1 2) (integer 3 4)) . (integer -1 4))
+ ;; 19
+ ((or (integer -1 3) (integer 3 4)) . (integer -1 4))
+ ;; 20
+ ((or (integer -1 4) (integer 3 4)) . (integer -1 4))
+ ;; 21
+ ((or (integer -1 5) (integer 3 4)) . (integer -1 5))
+ ;; 22
+ ((or (integer -1 *) (integer 3 4)) . (integer -1 *))
+ ;; 23
+ ((or (integer -1 2) (integer * 4)) . (integer * 4))
+ ;; 24
+ ((and string array) . string)
+ ;; 25
+ ((and cons atom) . nil)
+ ;; 26
+ ((and (member foo) (member foo bar baz)) . (member foo))
+ ;; 27
+ ((and (member foo) (member bar)) . nil)
+ ;; 28
+ ((and (member foo) symbol) . (member foo))
+ ;; 29
+ ((and (member foo) string) . nil)
+ ;; 30
+ ((and (member foo) (integer 1 2)) . nil)
+ ;; 31
+ ((and (member 1 2) (member 3 2)) . (integer 2 2))
+ ;; 32
+ ((and number (integer 1 2)) . (integer 1 2))
+ ;; 33
+ ((and integer (integer 1 2)) . (integer 1 2))
+ ;; 34
+ ((and (integer -1 0) (integer 3 5)) . nil)
+ ;; 35
+ ((and (integer -1 2) (integer 3 5)) . nil)
+ ;; 36
+ ((and (integer -1 3) (integer 3 5)) . (integer 3 3))
+ ;; 37
+ ((and (integer -1 4) (integer 3 5)) . (integer 3 4))
+ ;; 38
+ ((and (integer -1 5) nil) . nil)
+ ;; 39
+ ((not symbol) . (not symbol))
+ ;; 40
+ ((or (member foo) (not (member foo bar))) . (not (member bar)))
+ ;; 41
+ ((or (member foo bar) (not (member foo))) . t)
+ ;; 42
+ ((or symbol (not sequence)) . (not sequence))
+ ;; 43
+ ((or symbol (not symbol)) . t)
+ ;; 44
+ ((or symbol (not sequence)) . (not sequence))
+ ;; 45 Conservative.
+ ((or vector (not sequence)) . t)
+ ;; 46
+ ((or (integer 1 10) (not (integer * 5))) . (not (integer * 0)))
+ ;; 47
+ ((or symbol (integer 1 10) (not (integer * 5))) . (not (integer * 0)))
+ ;; 48
+ ((or (not symbol) (integer 1 10) (not (integer * 5))) . (not (or symbol (integer * 0))))
+ ;; 49
+ ((or symbol (not (member foo))) . (not (member foo)))
+ ;; 50
+ ((or (not symbol) (not (member foo))) . (not symbol))
+ ;; 51 Conservative.
+ ((or (not (member foo)) string) . (not (member foo)))
+ ;; 52 Conservative.
+ ((or (member foo) (not string)) . (not string))
+ ;; 53
+ ((or (not (integer 1 2)) integer) . t)
+ ;; 54
+ ((or (not (integer 1 2)) (not integer)) . (not integer))
+ ;; 55
+ ((or (integer 1 2) (not integer)) . (not (or (integer * 0) (integer 3 *))))
+ ;; 56
+ ((or number (not (integer 1 2))) . t)
+ ;; 57
+ ((or atom (not (integer 1 2))) . t)
+ ;; 58
+ ((or atom (not (member foo))) . t)
+ ;; 59
+ ((and symbol (not cons)) . symbol)
+ ;; 60
+ ((and symbol (not symbol)) . nil)
+ ;; 61
+ ((and atom (not symbol)) . atom)
+ ;; 62
+ ((and atom (not string)) . (or array sequence atom))
+ ;; 63 Conservative
+ ((and symbol (not (member foo))) . symbol)
+ ;; 64 Conservative
+ ((and symbol (not (member 3))) . symbol)
+ ;; 65
+ ((and (not (member foo)) (integer 1 10)) . (integer 1 10))
+ ;; 66
+ ((and (member foo) (not (integer 1 10))) . (member foo))
+ ;; 67
+ ((and t (not (member foo))) . (not (member foo)))
+ ;; 68
+ ((and integer (not (integer 3 4))) . (or (integer * 2) (integer 5 *)))
+ ;; 69
+ ((and (integer 0 20) (not (integer 5 10))) . (or (integer 0 4) (integer 11 20)))
+ ;; 70
+ ((and (not (member a)) (not (member b))) . (not (member a b)))
+ ;; 71
+ ((and (not boolean) (not (member b))) . (not (or (member b) boolean)))
+ ;; 72
+ ((and t (integer 1 1)) . (integer 1 1))
+ ;; 73
+ ((not (integer -1 5)) . (not (integer -1 5)))
+ ;; 74
+ ((and boolean (or number marker)) . nil)
+ ;; 75
+ ((and atom (or number marker)) . (or marker number))
+ ;; 76
+ ((and symbol (or number marker)) . nil)
+ ;; 77
+ ((and (or symbol string) (or number marker)) . nil)
+ ;; 78
+ ((and t t) . t)
+ ;; 80
+ ((and (or marker number) (integer 0 0)) . (integer 0 0))
+ ;; 81
+ ((and t (not t)) . nil)
+ ;; 82
+ ((or (integer 1 1) (not (integer 1 1))) . t)
+ ;; 83
+ ((not t) . nil)
+ ;; 84
+ ((not nil) . t)
+ ;; 85
+ ((or (not string) t) . t)
+ ;; 86
+ ((or (not vector) sequence) . sequence)
+ ;; 87
+ ((or (not symbol) null) . t))
+ "Alist type specifier -> expected type specifier."))
+
+(defmacro comp-cstr-synthesize-tests ()
+ "Generate all tests from `comp-cstr-typespec-tests-alist'."
+ `(progn
+ ,@(cl-loop
+ for i from 1
+ for (ts . exp-ts) in comp-cstr-typespec-tests-alist
+ append (list (comp-cstr-typespec-test i ts exp-ts)))))
+
+(comp-cstr-synthesize-tests)
+
+;;; comp-cstr-tests.el ends here
diff --git a/test/lisp/help-fns-tests.el b/test/lisp/help-fns-tests.el
index 80d90daaf91..099d627f355 100644
--- a/test/lisp/help-fns-tests.el
+++ b/test/lisp/help-fns-tests.el
@@ -62,12 +62,16 @@ Return first line of the output of (describe-function-1 FUNC)."
(should (string-match regexp result))))
(ert-deftest help-fns-test-lisp-defun ()
- (let ((regexp "a compiled Lisp function in .+subr\\.el")
+ (let ((regexp (if (boundp 'comp-ctxt)
+ "a native compiled Lisp function in .+subr\\.el"
+ "a compiled Lisp function in .+subr\\.el"))
(result (help-fns-tests--describe-function 'last)))
(should (string-match regexp result))))
(ert-deftest help-fns-test-lisp-defsubst ()
- (let ((regexp "a compiled Lisp function in .+subr\\.el")
+ (let ((regexp (if (boundp 'comp-ctxt)
+ "a native compiled Lisp function in .+subr\\.el"
+ "a compiled Lisp function in .+subr\\.el"))
(result (help-fns-tests--describe-function 'posn-window)))
(should (string-match regexp result))))
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index 7a116aa1299..8fa3917a0b9 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -382,7 +382,7 @@ cf. Bug#25477."
"Test for https://debbugs.gnu.org/22027 ."
(let ((default "foo") res)
(cl-letf (((symbol-function 'read-string)
- (lambda (_prompt _init _hist def) def)))
+ (lambda (_prompt _init _hist def _inher-input) def)))
(setq res (read-passwd "pass: " 'confirm (mapconcat #'string default "")))
(should (string= default res)))))
diff --git a/test/src/comp-test-45603.el b/test/src/comp-test-45603.el
new file mode 100644
index 00000000000..f1c0dafb68d
--- /dev/null
+++ b/test/src/comp-test-45603.el
@@ -0,0 +1,28 @@
+;;; -*- lexical-binding: t; -*-
+
+;; Reduced from ivy.el.
+
+(defvar comp-test-45603-last)
+(defvar comp-test-45603-mark-prefix)
+(defvar comp-test-45603-directory)
+(defvar comp-test-45603-marked-candidates)
+
+(defun comp-test-45603--call-marked (action)
+ (let* ((prefix-len (length comp-test-45603-mark-prefix))
+ (marked-candidates
+ (mapcar
+ (lambda (s)
+ (let ((cand (substring s prefix-len)))
+ (if comp-test-45603-directory
+ (expand-file-name cand comp-test-45603-directory)
+ cand)))
+ comp-test-45603-marked-candidates))
+ (multi-action (comp-test-45603--get-multi-action comp-test-45603-last)))))
+
+(defalias 'comp-test-45603--file-local-name
+ (if (fboundp 'file-local-name)
+ #'file-local-name
+ (lambda (file)
+ (or (file-remote-p file 'localname) file))))
+
+(provide 'comp-test-45603)
diff --git a/test/src/comp-test-funcs-dyn.el b/test/src/comp-test-funcs-dyn.el
new file mode 100644
index 00000000000..67db7587bf9
--- /dev/null
+++ b/test/src/comp-test-funcs-dyn.el
@@ -0,0 +1,50 @@
+;;; comp-test-funcs-dyn.el --- compilation unit tested by comp-tests.el -*- lexical-binding: nil; -*-
+
+;; Copyright (C) 2020 Free Software Foundation, Inc.
+
+;; Author: Andrea Corallo <akrl@sdf.org>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defun comp-tests-ffuncall-callee-dyn-f (a b)
+ (list a b))
+
+(defun comp-tests-ffuncall-callee-opt-dyn-f (a b &optional c d)
+ (list a b c d))
+
+(defun comp-tests-ffuncall-callee-rest-dyn-f (a b &rest c)
+ (list a b c))
+
+(defun comp-tests-ffuncall-callee-opt-rest-dyn-f (a b &optional c &rest d)
+ (list a b c d))
+
+(defun comp-tests-cl-macro-exp-f ()
+ (cl-loop for xxx in '(a b)
+ for yyy = xxx
+ collect xxx))
+
+(cl-defun comp-tests-cl-uninterned-arg-parse-f (a &optional b &aux)
+ (list a b))
+
+(provide 'comp-test-dyn-funcs)
+
+;;; comp-test-funcs-dyn.el ends here
diff --git a/test/src/comp-test-funcs.el b/test/src/comp-test-funcs.el
new file mode 100644
index 00000000000..f2a246320ac
--- /dev/null
+++ b/test/src/comp-test-funcs.el
@@ -0,0 +1,710 @@
+;;; comp-test-funcs.el --- compilation unit tested by comp-tests.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019-2021 Free Software Foundation, Inc.
+
+;; Author: Andrea Corallo <akrl@sdf.org>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(defvar comp-tests-var1 3)
+
+(defun comp-tests-varref-f ()
+ comp-tests-var1)
+
+(defun comp-tests-list-f ()
+ (list 1 2 3))
+(defun comp-tests-list2-f (a b c)
+ (list a b c))
+(defun comp-tests-car-f (x)
+ ;; Bcar
+ (car x))
+(defun comp-tests-cdr-f (x)
+ ;; Bcdr
+ (cdr x))
+(defun comp-tests-car-safe-f (x)
+ ;; Bcar_safe
+ (car-safe x))
+(defun comp-tests-cdr-safe-f (x)
+ ;; Bcdr_safe
+ (cdr-safe x))
+
+(defun comp-tests-cons-car-f ()
+ (car (cons 1 2)))
+(defun comp-tests-cons-cdr-f (x)
+ (cdr (cons 'foo x)))
+
+(defun comp-tests-hint-fixnum-f (n)
+ (1+ (comp-hint-fixnum n)))
+
+(defun comp-tests-hint-cons-f (c)
+ (car (comp-hint-cons c)))
+
+(defun comp-tests-varset0-f ()
+ (setq comp-tests-var1 55))
+(defun comp-tests-varset1-f ()
+ (setq comp-tests-var1 66)
+ 4)
+
+(defun comp-tests-length-f ()
+ (length '(1 2 3)))
+
+(defun comp-tests-aref-aset-f ()
+ (let ((vec (make-vector 3 0)))
+ (aset vec 2 100)
+ (aref vec 2)))
+
+(defvar comp-tests-var2 3)
+(defun comp-tests-symbol-value-f ()
+ (symbol-value 'comp-tests-var2))
+
+(defun comp-tests-concat-f (x)
+ (concat "a" "b" "c" "d"
+ (concat "a" "b" "c" (concat "a" "b" (concat "foo" x)))))
+
+(defun comp-tests-ffuncall-callee-f (x y z)
+ (list x y z))
+
+(defun comp-tests-ffuncall-callee-optional-f (a b &optional c d)
+ (list a b c d))
+
+(defun comp-tests-ffuncall-callee-rest-f (a b &rest c)
+ (list a b c))
+
+(defun comp-tests-ffuncall-callee-more8-f (p1 p2 p3 p4 p5 p6 p7 p8 p9 p10)
+ ;; More then 8 args.
+ (list p1 p2 p3 p4 p5 p6 p7 p8 p9 p10))
+
+(defun comp-tests-ffuncall-callee-more8-rest-f (p1 p2 p3 p4 p5 p6 p7 p8 p9 &rest p10)
+ ;; More then 8 args.
+ (list p1 p2 p3 p4 p5 p6 p7 p8 p9 p10))
+
+(defun comp-tests-ffuncall-native-f ()
+ "Call a primitive with no dedicate op."
+ (make-vector 1 nil))
+
+(defun comp-tests-ffuncall-native-rest-f ()
+ "Call a primitive with no dedicate op with &rest."
+ (vector 1 2 3))
+
+(defun comp-tests-ffuncall-apply-many-f (x)
+ (apply #'list x))
+
+(defun comp-tests-ffuncall-lambda-f (x)
+ (let ((fun (lambda (x)
+ (1+ x))))
+ (funcall fun x)))
+
+(defun comp-tests-jump-table-1-f (x)
+ (pcase x
+ ('x 'a)
+ ('y 'b)
+ (_ 'c)))
+
+(defun comp-tests-jump-table-2-f (x)
+ (pcase x
+ ("aaa" 'a)
+ ("bbb" 'b)))
+
+(defun comp-tests-conditionals-1-f (x)
+ ;; Generate goto-if-nil
+ (if x 1 2))
+(defun comp-tests-conditionals-2-f (x)
+ ;; Generate goto-if-nil-else-pop
+ (when x
+ 1340))
+
+(defun comp-tests-fixnum-1-minus-f (x)
+ ;; Bsub1
+ (1- x))
+(defun comp-tests-fixnum-1-plus-f (x)
+ ;; Badd1
+ (1+ x))
+(defun comp-tests-fixnum-minus-f (x)
+ ;; Bnegate
+ (- x))
+
+(defun comp-tests-eqlsign-f (x y)
+ ;; Beqlsign
+ (= x y))
+(defun comp-tests-gtr-f (x y)
+ ;; Bgtr
+ (> x y))
+(defun comp-tests-lss-f (x y)
+ ;; Blss
+ (< x y))
+(defun comp-tests-les-f (x y)
+ ;; Bleq
+ (<= x y))
+(defun comp-tests-geq-f (x y)
+ ;; Bgeq
+ (>= x y))
+
+(defun comp-tests-setcar-f (x y)
+ (setcar x y)
+ x)
+(defun comp-tests-setcdr-f (x y)
+ (setcdr x y)
+ x)
+
+(defun comp-bubble-sort-f (list)
+ (let ((i (length list)))
+ (while (> i 1)
+ (let ((b list))
+ (while (cdr b)
+ (when (< (cadr b) (car b))
+ (setcar b (prog1 (cadr b)
+ (setcdr b (cons (car b) (cddr b))))))
+ (setq b (cdr b))))
+ (setq i (1- i)))
+ list))
+
+(defun comp-tests-consp-f (x)
+ ;; Bconsp
+ (consp x))
+(defun comp-tests-setcar2-f (x)
+ ;; Bsetcar
+ (setcar x 3))
+
+(defun comp-tests-integerp-f (x)
+ ;; Bintegerp
+ (integerp x))
+(defun comp-tests-numberp-f (x)
+ ;; Bnumberp
+ (numberp x))
+
+(defun comp-tests-discardn-f (x)
+ ;; BdiscardN
+ (1+ (let ((a 1)
+ (_b)
+ (_c))
+ a)))
+(defun comp-tests-insertn-f (a b c d)
+ ;; Binsert
+ (insert a b c d))
+
+(defun comp-tests-err-arith-f ()
+ (/ 1 0))
+(defun comp-tests-err-foo-f ()
+ (error "foo"))
+
+(defun comp-tests-condition-case-0-f ()
+ ;; Bpushhandler Bpophandler
+ (condition-case
+ err
+ (comp-tests-err-arith-f)
+ (arith-error (concat "arith-error "
+ (error-message-string err)
+ " catched"))
+ (error (concat "error "
+ (error-message-string err)
+ " catched"))))
+(defun comp-tests-condition-case-1-f ()
+ ;; Bpushhandler Bpophandler
+ (condition-case
+ err
+ (comp-tests-err-foo-f)
+ (arith-error (concat "arith-error "
+ (error-message-string err)
+ " catched"))
+ (error (concat "error "
+ (error-message-string err)
+ " catched"))))
+(defun comp-tests-catch-f (f)
+ (catch 'foo
+ (funcall f)))
+(defun comp-tests-throw-f (x)
+ (throw 'foo x))
+
+(defun comp-tests-buff0-f ()
+ (with-temp-buffer
+ (insert "foo")
+ (buffer-string)))
+
+(defun comp-tests-lambda-return-f ()
+ (lambda (x) (1+ x)))
+
+(defun comp-tests-fib-f (n)
+ (cond ((= n 0) 0)
+ ((= n 1) 1)
+ (t (+ (comp-tests-fib-f (- n 1))
+ (comp-tests-fib-f (- n 2))))))
+
+(defmacro comp-tests-macro-m (x)
+ x)
+
+(defun comp-tests-string-trim-f (url)
+ (string-trim url))
+
+(defun comp-tests-trampoline-removal-f ()
+ (make-hash-table))
+
+(defun comp-tests-signal-f ()
+ (signal 'foo t))
+
+(defun comp-tests-func-call-removal-f ()
+ (let ((a 10)
+ (b 3))
+ (% a b)))
+
+(defun comp-tests-doc-f ()
+ "A nice docstring"
+ t)
+
+(defun comp-test-interactive-form0-f (dir)
+ (interactive "D")
+ dir)
+
+(defun comp-test-interactive-form1-f (x y)
+ (interactive '(1 2))
+ (+ x y))
+
+(defun comp-test-interactive-form2-f ()
+ (interactive))
+
+(defun comp-test-40187-2-f ()
+ 'foo)
+
+(defalias 'comp-test-40187-1-f (symbol-function 'comp-test-40187-2-f))
+
+(defun comp-test-40187-2-f ()
+ 'bar)
+
+(defun comp-test-speed--1-f ()
+ (declare (speed -1))
+ 3)
+
+(defun comp-test-42360-f (str end-column
+ &optional start-column padding ellipsis
+ ellipsis-text-property)
+ ;; From `truncate-string-to-width'. A large enough function to
+ ;; potentially use all registers and that is modifying local
+ ;; variables inside condition-case.
+ (let ((str-len (length str))
+ (str-width 14)
+ (ellipsis-width 3)
+ (idx 0)
+ (column 0)
+ (head-padding "") (tail-padding "")
+ ch last-column last-idx from-idx)
+ (condition-case nil
+ (while (< column start-column)
+ (setq ch (aref str idx)
+ column (+ column (char-width ch))
+ idx (1+ idx)))
+ (args-out-of-range (setq idx str-len)))
+ (if (< column start-column)
+ (if padding (make-string end-column padding) "")
+ (when (and padding (> column start-column))
+ (setq head-padding (make-string (- column start-column) padding)))
+ (setq from-idx idx)
+ (when (>= end-column column)
+ (condition-case nil
+ (while (< column end-column)
+ (setq last-column column
+ last-idx idx
+ ch (aref str idx)
+ column (+ column (char-width ch))
+ idx (1+ idx)))
+ (args-out-of-range (setq idx str-len)))
+ (when (> column end-column)
+ (setq column last-column
+ idx last-idx))
+ (when (and padding (< column end-column))
+ (setq tail-padding (make-string (- end-column column) padding))))
+ (if (and ellipsis-text-property
+ (not (equal ellipsis ""))
+ idx)
+ (concat head-padding
+ (substring str from-idx idx)
+ (propertize (substring str idx) 'display (or ellipsis "")))
+ (concat head-padding (substring str from-idx idx)
+ tail-padding ellipsis)))))
+
+(defun comp-test-primitive-advice-f (x y)
+ (declare (speed 2))
+ (+ x y))
+
+(defun comp-test-primitive-redefine-f (x y)
+ (declare (speed 2))
+ (- x y))
+
+(defsubst comp-test-defsubst-f ()
+ t)
+
+(defvar comp-test-and-3-var 1)
+(defun comp-test-and-3-f (x)
+ (and (atom x)
+ comp-test-and-3-var
+ 2))
+
+(defun comp-test-copy-insn-f (insn)
+ ;; From `comp-copy-insn'.
+ (if (consp insn)
+ (let (result)
+ (while (consp insn)
+ (let ((newcar (car insn)))
+ (if (or (consp (car insn)) (comp-mvar-p (car insn)))
+ (setf newcar (comp-copy-insn (car insn))))
+ (push newcar result))
+ (setf insn (cdr insn)))
+ (nconc (nreverse result)
+ (if (comp-mvar-p insn) (comp-copy-insn insn) insn)))
+ (if (comp-mvar-p insn)
+ (copy-comp-mvar insn)
+ insn)))
+
+(defun comp-test-cond-rw-1-1-f ())
+
+(defun comp-test-cond-rw-1-2-f ()
+ (let ((it (comp-test-cond-rw-1-1-f))
+ (key 't))
+ (if (or (equal it key)
+ (eq key t))
+ it
+ nil)))
+
+(defun comp-test-44968-f (start end)
+ (let ((dirlist)
+ (dir (expand-file-name start))
+ (end (expand-file-name end)))
+ (while (not (or (equal dir (car dirlist))
+ (file-equal-p dir end)))
+ (push dir dirlist)
+ (setq dir (directory-file-name (file-name-directory dir))))
+ (nreverse dirlist)))
+
+(defun comp-test-45342-f (n)
+ (pcase n
+ (1 " ➊") (2 " ➋") (3 " ➌") (4 " ➍") (5 " ➎") (6 " ➏")
+ (7 " ➐") (8 " ➑") (9 " ➒") (10 " ➓") (_ "")))
+
+(defun comp-test-assume-double-neg-f (collection value)
+ ;; Reduced from `auth-source-search-collection'.
+ (when (atom collection)
+ (setq collection (list collection)))
+ (or (eq value t)
+ ;; value is (not (member t))
+ (eq collection value)
+ ;; collection is t, not (member t)!
+ (member value collection)))
+
+(defun comp-test-assume-in-loop-1-f (arg)
+ ;; Reduced from `comint-delim-arg'.
+ (let ((args nil)
+ (pos 0)
+ (len (length arg)))
+ (while (< pos len)
+ (let ((start pos))
+ (while (< pos len)
+ (setq pos (1+ pos)))
+ (setq args (cons (substring arg start pos) args))))
+ args))
+
+(defun comp-test-45376-1-f ()
+ ;; Reduced from `eshell-ls-find-column-lengths'.
+ (let* (res
+ (len 2)
+ (i 0)
+ (j 0))
+ (while (< j len)
+ (if (= i len)
+ (setq i 0))
+ (setq res (cons i res)
+ j (1+ j)
+ i (1+ i)))
+ res))
+
+(defun comp-test-45376-2-f ()
+ ;; Also reduced from `eshell-ls-find-column-lengths'.
+ (let* ((x 1)
+ res)
+ (while x
+ (let* ((y 4)
+ (i 0))
+ (while (> y 0)
+ (when (= i x)
+ (setq i 0))
+ (setf res (cons i res))
+ (setq y (1- y)
+ i (1+ i)))
+ (if (>= x 3)
+ (setq x nil)
+ (setq x (1+ x)))))
+ res))
+
+(defun comp-test-not-cons-f (x)
+ ;; Reduced from `cl-copy-list'.
+ (if (consp x)
+ (print x)
+ (car x)))
+
+(defun comp-test-45576-f ()
+ ;; Reduced from `eshell-find-alias-function'.
+ (let ((sym (intern-soft "eval")))
+ (if (and (functionp sym)
+ '(eshell-ls eshell-pred eshell-prompt eshell-script
+ eshell-term eshell-unix))
+ sym)))
+
+(defun comp-test-45635-f (&rest args)
+ ;; Reduced from `set-face-attribute'.
+ (let ((spec args)
+ family)
+ (while spec
+ (cond ((eq (car spec) :family)
+ (setq family (cadr spec))))
+ (setq spec (cddr spec)))
+ (when (and (stringp family)
+ (string-match "\\([^-]*\\)-\\([^-]*\\)" family))
+ (setq family (match-string 2 family)))
+ (when (or (stringp family)
+ (eq family 'unspecified))
+ family)))
+
+(defun comp-test-46670-1-f (_)
+ "foo")
+
+(defun comp-test-46670-2-f (s)
+ (and (equal (comp-test-46670-1-f (length s)) s)
+ s))
+
+(cl-defun comp-test-46824-1-f ()
+ (let ((next-repos '(1)))
+ (while t
+ (let ((recipe (car next-repos)))
+ (cl-block loop
+ (while t
+ (let ((err
+ (condition-case e
+ (progn
+ (setq next-repos
+ (cdr next-repos))
+ (cl-return-from loop))
+ (error e))))
+ (format "%S"
+ (error-message-string err))))))
+ (cl-return-from comp-test-46824-1-f))))
+
+(defun comp-test-47868-1-f ()
+ " ")
+
+(defun comp-test-47868-2-f ()
+ #(" " 0 1 (face font-lock-keyword-face)))
+
+(defun comp-test-47868-3-f ()
+ " ")
+
+(defun comp-test-47868-4-f ()
+ #(" " 0 1 (face font-lock-keyword-face)))
+
+
+
+;;;;;;;;;;;;;;;;;;;;
+;; Tromey's tests ;;
+;;;;;;;;;;;;;;;;;;;;
+
+;; Test Bconsp.
+(defun comp-test-consp (x) (consp x))
+
+;; Test Blistp.
+(defun comp-test-listp (x) (listp x))
+
+;; Test Bstringp.
+(defun comp-test-stringp (x) (stringp x))
+
+;; Test Bsymbolp.
+(defun comp-test-symbolp (x) (symbolp x))
+
+;; Test Bintegerp.
+(defun comp-test-integerp (x) (integerp x))
+
+;; Test Bnumberp.
+(defun comp-test-numberp (x) (numberp x))
+
+;; Test Badd1.
+(defun comp-test-add1 (x) (1+ x))
+
+;; Test Bsub1.
+(defun comp-test-sub1 (x) (1- x))
+
+;; Test Bneg.
+(defun comp-test-negate (x) (- x))
+
+;; Test Bnot.
+(defun comp-test-not (x) (not x))
+
+;; Test Bbobp, Beobp, Bpoint, Bpoint_min, Bpoint_max.
+(defun comp-test-bobp () (bobp))
+(defun comp-test-eobp () (eobp))
+(defun comp-test-point () (point))
+(defun comp-test-point-min () (point-min))
+(defun comp-test-point-max () (point-max))
+
+;; Test Bcar and Bcdr.
+(defun comp-test-car (x) (car x))
+(defun comp-test-cdr (x) (cdr x))
+
+;; Test Bcar_safe and Bcdr_safe.
+(defun comp-test-car-safe (x) (car-safe x))
+(defun comp-test-cdr-safe (x) (cdr-safe x))
+
+;; Test Beq.
+(defun comp-test-eq (x y) (eq x y))
+
+;; Test Bgotoifnil.
+(defun comp-test-if (x y) (if x x y))
+
+;; Test Bgotoifnilelsepop.
+(defun comp-test-and (x y) (and x y))
+
+;; Test Bgotoifnonnilelsepop.
+(defun comp-test-or (x y) (or x y))
+
+;; Test Bsave_excursion.
+(defun comp-test-save-excursion ()
+ (save-excursion
+ (insert "XYZ")))
+
+;; Test Bcurrent_buffer.
+(defun comp-test-current-buffer () (current-buffer))
+
+;; Test Bgtr.
+(defun comp-test-> (a b)
+ (> a b))
+
+;; Test Bpushcatch.
+(defun comp-test-catch (&rest l)
+ (catch 'done
+ (dolist (v l)
+ (when (> v 23)
+ (throw 'done v)))))
+
+;; Test Bmemq.
+(defun comp-test-memq (val list)
+ (memq val list))
+
+;; Test BlistN.
+(defun comp-test-listN (x)
+ (list x x x x x x x x x x x x x x x x))
+
+;; Test BconcatN.
+(defun comp-test-concatN (x)
+ (concat x x x x x x))
+
+;; Test optional and rest arguments.
+(defun comp-test-opt-rest (a &optional b &rest c)
+ (list a b c))
+
+;; Test for too many arguments.
+(defun comp-test-opt (a &optional b)
+ (cons a b))
+
+;; Test for unwind-protect.
+(defvar comp-test-up-val nil)
+(defun comp-test-unwind-protect (fun)
+ (setq comp-test-up-val nil)
+ (unwind-protect
+ (progn
+ (setq comp-test-up-val 23)
+ (funcall fun)
+ (setq comp-test-up-val 24))
+ (setq comp-test-up-val 999)))
+
+;; Non tested functions that proved just to be difficult to compile.
+
+(defun comp-test-callee (_ __) t)
+(defun comp-test-silly-frame1 (x)
+ ;; Check robustness against dead code.
+ (cl-case x
+ (0 (comp-test-callee
+ (pcase comp-tests-var1
+ (1 1)
+ (2 2))
+ 3))))
+
+(defun comp-test-silly-frame2 (token)
+ ;; Check robustness against dead code.
+ (while c
+ (cl-case c
+ (?< 1)
+ (?> 2))))
+
+(defun comp-test-big-interactive (filename &optional force arg load)
+ ;; Check non trivial interactive form using `byte-recompile-file'.
+ (interactive
+ (let ((file buffer-file-name)
+ (file-name nil)
+ (file-dir nil))
+ (and file
+ (derived-mode-p 'emacs-lisp-mode)
+ (setq file-name (file-name-nondirectory file)
+ file-dir (file-name-directory file)))
+ (list (read-file-name (if current-prefix-arg
+ "Byte compile file: "
+ "Byte recompile file: ")
+ file-dir file-name nil)
+ current-prefix-arg)))
+ (let ((dest (byte-compile-dest-file filename))
+ ;; Expand now so we get the current buffer's defaults
+ (filename (expand-file-name filename)))
+ (if (if (file-exists-p dest)
+ ;; File was already compiled
+ ;; Compile if forced to, or filename newer
+ (or force
+ (file-newer-than-file-p filename dest))
+ (and arg
+ (or (eq 0 arg)
+ (y-or-n-p (concat "Compile "
+ filename "? ")))))
+ (progn
+ (if (and noninteractive (not byte-compile-verbose))
+ (message "Compiling %s..." filename))
+ (byte-compile-file filename load))
+ (when load
+ (load (if (file-exists-p dest) dest filename)))
+ 'no-byte-compile)))
+
+(defun comp-test-no-return-1 (x)
+ (while x
+ (error "foo")))
+
+(defun comp-test-no-return-2 (x)
+ (cond
+ ((eql x '2) t)
+ ((error "bar") nil)))
+
+(defun comp-test-no-return-3 ())
+(defun comp-test-no-return-4 (x)
+ (when x
+ (error "foo")
+ (while (comp-test-no-return-3)
+ (comp-test-no-return-3))))
+
+(defun comp-test-=-nan (x)
+ (when (= x 0.0e+NaN)
+ x))
+
+(defun comp-test-=-infinity (x)
+ (when (= x 1.0e+INF)
+ x))
+
+(provide 'comp-test-funcs)
+
+;;; comp-test-funcs.el ends here
diff --git a/test/src/comp-test-pure.el b/test/src/comp-test-pure.el
new file mode 100644
index 00000000000..f606a44a10e
--- /dev/null
+++ b/test/src/comp-test-pure.el
@@ -0,0 +1,40 @@
+;;; comp-test-pure.el --- compilation unit tested by comp-tests.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Free Software Foundation, Inc.
+
+;; Author: Andrea Corallo <akrl@sdf.org>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(defun comp-tests-pure-callee-f (x)
+ (1+ x))
+
+(defun comp-tests-pure-caller-f ()
+ (comp-tests-pure-callee-f 3))
+
+(defun comp-tests-pure-fibn-f (a b count)
+ (if (= count 0)
+ b
+ (comp-tests-pure-fibn-f (+ a b) a (- count 1))))
+
+(defun comp-tests-pure-fibn-entry-f ()
+ (comp-tests-pure-fibn-f 1 0 20))
+
+;;; comp-test-pure.el ends here
diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el
new file mode 100644
index 00000000000..a1e91ec5141
--- /dev/null
+++ b/test/src/comp-tests.el
@@ -0,0 +1,1446 @@
+;;; comp-tests.el --- unit tests for src/comp.c -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019-2021 Free Software Foundation, Inc.
+
+;; Author: Andrea Corallo <akrl@sdf.org>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Unit tests for src/comp.c.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+(require 'comp)
+
+(defconst comp-test-directory (file-name-directory (or load-file-name
+ buffer-file-name)))
+(defconst comp-test-src
+ (concat comp-test-directory "comp-test-funcs.el"))
+
+(defconst comp-test-dyn-src
+ (concat comp-test-directory "comp-test-funcs-dyn.el"))
+
+(when (featurep 'nativecomp)
+ (message "Compiling tests...")
+ (load (native-compile comp-test-src))
+ (load (native-compile comp-test-dyn-src)))
+
+(defmacro comp-deftest (name args &rest docstring-and-body)
+ "Define a test for the native compiler tagging it as :nativecomp."
+ (declare (indent defun)
+ (doc-string 3))
+ `(ert-deftest ,(intern (concat "comp-tests-" (symbol-name name))) ,args
+ :tags '(:nativecomp)
+ ,@docstring-and-body))
+
+
+
+(ert-deftest comp-tests-bootstrap ()
+ "Compile the compiler and load it to compile it-self.
+Check that the resulting binaries do not differ."
+ :tags '(:expensive-test :nativecomp)
+ (let* ((byte-native-for-bootstrap t) ; FIXME HACK
+ (comp-src (concat comp-test-directory
+ "../../lisp/emacs-lisp/comp.el"))
+ (comp1-src (make-temp-file "stage1-" nil ".el"))
+ (comp2-src (make-temp-file "stage2-" nil ".el"))
+ ;; Can't use debug symbols.
+ (comp-debug 0))
+ (copy-file comp-src comp1-src t)
+ (copy-file comp-src comp2-src t)
+ (let ((load-no-native t))
+ (load (concat comp-src "c") nil nil t t))
+ (should-not (subr-native-elisp-p (symbol-function #'native-compile)))
+ (message "Compiling stage1...")
+ (let* ((t0 (current-time))
+ (comp1-eln (native-compile comp1-src)))
+ (message "Done in %d secs" (float-time (time-since t0)))
+ (load comp1-eln nil nil t t)
+ (should (subr-native-elisp-p (symbol-function 'native-compile)))
+ (message "Compiling stage2...")
+ (let ((t0 (current-time))
+ (comp2-eln (native-compile comp2-src)))
+ (message "Done in %d secs" (float-time (time-since t0)))
+ (message "Comparing %s %s" comp1-eln comp2-eln)
+ (should (= (call-process "cmp" nil nil nil comp1-eln comp2-eln) 0))))))
+
+(comp-deftest provide ()
+ "Testing top level provide."
+ (should (featurep 'comp-test-funcs)))
+
+(comp-deftest varref ()
+ "Testing varref."
+ (should (= (comp-tests-varref-f) 3)))
+
+(comp-deftest list ()
+ "Testing cons car cdr."
+ (should (equal (comp-tests-list-f) '(1 2 3)))
+ (should (equal (comp-tests-list2-f 1 2 3) '(1 2 3)))
+ (should (= (comp-tests-car-f '(1 . 2)) 1))
+ (should (null (comp-tests-car-f nil)))
+ (should-error (comp-tests-car-f 3)
+ :type 'wrong-type-argument)
+ (should (= (comp-tests-cdr-f '(1 . 2)) 2))
+ (should (null (comp-tests-cdr-f nil)))
+ (should-error (comp-tests-cdr-f 3)
+ :type 'wrong-type-argument)
+ (should (= (comp-tests-car-safe-f '(1 . 2)) 1))
+ (should (null (comp-tests-car-safe-f 'a)))
+ (should (= (comp-tests-cdr-safe-f '(1 . 2)) 2))
+ (should (null (comp-tests-cdr-safe-f 'a))))
+
+(comp-deftest comp-tests-cons-car-cdr ()
+ "Testing cons car cdr."
+ (should (= (comp-tests-cons-car-f) 1))
+ (should (= (comp-tests-cons-cdr-f 3) 3)))
+
+(comp-deftest varset ()
+ "Testing varset."
+ (comp-tests-varset0-f)
+ (should (= comp-tests-var1 55))
+
+ (should (= (comp-tests-varset1-f) 4))
+ (should (= comp-tests-var1 66)))
+
+(comp-deftest length ()
+ "Testing length."
+ (should (= (comp-tests-length-f) 3)))
+
+(comp-deftest aref-aset ()
+ "Testing aref and aset."
+ (should (= (comp-tests-aref-aset-f) 100)))
+
+(comp-deftest symbol-value ()
+ "Testing aref and aset."
+ (should (= (comp-tests-symbol-value-f) 3)))
+
+(comp-deftest concat ()
+ "Testing concatX opcodes."
+ (should (string= (comp-tests-concat-f "bar") "abcdabcabfoobar")))
+
+(comp-deftest ffuncall ()
+ "Test calling conventions."
+
+ ;; (defun comp-tests-ffuncall-caller-f ()
+ ;; (comp-tests-ffuncall-callee-f 1 2 3))
+
+ ;; (should (equal (comp-tests-ffuncall-caller-f) '(1 2 3)))
+
+ ;; ;; After it gets compiled
+ ;; (native-compile #'comp-tests-ffuncall-callee-f)
+ ;; (should (equal (comp-tests-ffuncall-caller-f) '(1 2 3)))
+
+ ;; ;; Recompiling the caller once with callee already compiled
+ ;; (defun comp-tests-ffuncall-caller-f ()
+ ;; (comp-tests-ffuncall-callee-f 1 2 3))
+ ;; (should (equal (comp-tests-ffuncall-caller-f) '(1 2 3)))
+
+ (should (equal (comp-tests-ffuncall-callee-optional-f 1 2 3 4)
+ '(1 2 3 4)))
+ (should (equal (comp-tests-ffuncall-callee-optional-f 1 2 3)
+ '(1 2 3 nil)))
+ (should (equal (comp-tests-ffuncall-callee-optional-f 1 2)
+ '(1 2 nil nil)))
+
+ (should (equal (comp-tests-ffuncall-callee-rest-f 1 2)
+ '(1 2 nil)))
+ (should (equal (comp-tests-ffuncall-callee-rest-f 1 2 3)
+ '(1 2 (3))))
+ (should (equal (comp-tests-ffuncall-callee-rest-f 1 2 3 4)
+ '(1 2 (3 4))))
+
+ (should (equal (comp-tests-ffuncall-callee-more8-f 1 2 3 4 5 6 7 8 9 10)
+ '(1 2 3 4 5 6 7 8 9 10)))
+
+ (should (equal (comp-tests-ffuncall-callee-more8-rest-f 1 2 3 4 5 6 7 8 9 10 11)
+ '(1 2 3 4 5 6 7 8 9 (10 11))))
+
+ (should (equal (comp-tests-ffuncall-native-f) [nil]))
+
+ (should (equal (comp-tests-ffuncall-native-rest-f) [1 2 3]))
+
+ (should (equal (comp-tests-ffuncall-apply-many-f '(1 2 3))
+ '(1 2 3)))
+
+ (should (= (comp-tests-ffuncall-lambda-f 1) 2)))
+
+(comp-deftest jump-table ()
+ "Testing jump tables"
+ (should (eq (comp-tests-jump-table-1-f 'x) 'a))
+ (should (eq (comp-tests-jump-table-1-f 'y) 'b))
+ (should (eq (comp-tests-jump-table-1-f 'xxx) 'c))
+
+ ;; Jump table not with eq as test
+ (should (eq (comp-tests-jump-table-2-f "aaa") 'a))
+ (should (eq (comp-tests-jump-table-2-f "bbb") 'b)))
+
+(comp-deftest conditionals ()
+ "Testing conditionals."
+ (should (= (comp-tests-conditionals-1-f t) 1))
+ (should (= (comp-tests-conditionals-1-f nil) 2))
+ (should (= (comp-tests-conditionals-2-f t) 1340))
+ (should (eq (comp-tests-conditionals-2-f nil) nil)))
+
+(comp-deftest fixnum ()
+ "Testing some fixnum inline operation."
+ (should (= (comp-tests-fixnum-1-minus-f 10) 9))
+ (should (= (comp-tests-fixnum-1-minus-f most-negative-fixnum)
+ (1- most-negative-fixnum)))
+ (should-error (comp-tests-fixnum-1-minus-f 'a)
+ :type 'wrong-type-argument)
+ (should (= (comp-tests-fixnum-1-plus-f 10) 11))
+ (should (= (comp-tests-fixnum-1-plus-f most-positive-fixnum)
+ (1+ most-positive-fixnum)))
+ (should-error (comp-tests-fixnum-1-plus-f 'a)
+ :type 'wrong-type-argument)
+ (should (= (comp-tests-fixnum-minus-f 10) -10))
+ (should (= (comp-tests-fixnum-minus-f most-negative-fixnum)
+ (- most-negative-fixnum)))
+ (should-error (comp-tests-fixnum-minus-f 'a)
+ :type 'wrong-type-argument))
+
+(comp-deftest type-hints ()
+ "Just test compiler hints are transparent in this case."
+ ;; FIXME we should really check they are also effective.
+ (should (= (comp-tests-hint-fixnum-f 3) 4))
+ (should (= (comp-tests-hint-cons-f (cons 1 2)) 1)))
+
+(comp-deftest arith-comp ()
+ "Testing arithmetic comparisons."
+ (should (eq (comp-tests-eqlsign-f 4 3) nil))
+ (should (eq (comp-tests-eqlsign-f 3 3) t))
+ (should (eq (comp-tests-eqlsign-f 2 3) nil))
+ (should (eq (comp-tests-gtr-f 4 3) t))
+ (should (eq (comp-tests-gtr-f 3 3) nil))
+ (should (eq (comp-tests-gtr-f 2 3) nil))
+ (should (eq (comp-tests-lss-f 4 3) nil))
+ (should (eq (comp-tests-lss-f 3 3) nil))
+ (should (eq (comp-tests-lss-f 2 3) t))
+ (should (eq (comp-tests-les-f 4 3) nil))
+ (should (eq (comp-tests-les-f 3 3) t))
+ (should (eq (comp-tests-les-f 2 3) t))
+ (should (eq (comp-tests-geq-f 4 3) t))
+ (should (eq (comp-tests-geq-f 3 3) t))
+ (should (eq (comp-tests-geq-f 2 3) nil)))
+
+(comp-deftest setcarcdr ()
+ "Testing setcar setcdr."
+ (should (equal (comp-tests-setcar-f '(10 . 10) 3) '(3 . 10)))
+ (should (equal (comp-tests-setcdr-f '(10 . 10) 3) '(10 . 3)))
+ (should-error (comp-tests-setcar-f 3 10)
+ :type 'wrong-type-argument)
+ (should-error (comp-tests-setcdr-f 3 10)
+ :type 'wrong-type-argument))
+
+(comp-deftest bubble-sort ()
+ "Run bubble sort."
+ (let* ((list1 (mapcar #'random (make-list 1000 most-positive-fixnum)))
+ (list2 (copy-sequence list1)))
+ (should (equal (comp-bubble-sort-f list1)
+ (sort list2 #'<)))))
+
+(comp-deftest apply ()
+ "Test some inlined list functions."
+ (should (eq (comp-tests-consp-f '(1)) t))
+ (should (eq (comp-tests-consp-f 1) nil))
+ (let ((x (cons 1 2)))
+ (should (= (comp-tests-setcar2-f x) 3))
+ (should (equal x '(3 . 2)))))
+
+(comp-deftest num-inline ()
+ "Test some inlined number functions."
+ (should (eq (comp-tests-integerp-f 1) t))
+ (should (eq (comp-tests-integerp-f '(1)) nil))
+ (should (eq (comp-tests-integerp-f 3.5) nil))
+ (should (eq (comp-tests-integerp-f (1+ most-negative-fixnum)) t))
+
+ (should (eq (comp-tests-numberp-f 1) t))
+ (should (eq (comp-tests-numberp-f 'a) nil))
+ (should (eq (comp-tests-numberp-f 3.5) t)))
+
+(comp-deftest stack ()
+ "Test some stack operation."
+ (should (= (comp-tests-discardn-f 10) 2))
+ (should (string= (with-temp-buffer
+ (comp-tests-insertn-f "a" "b" "c" "d")
+ (buffer-string))
+ "abcd")))
+
+(comp-deftest non-locals ()
+ "Test non locals."
+ (should (string= (comp-tests-condition-case-0-f)
+ "arith-error Arithmetic error catched"))
+ (should (string= (comp-tests-condition-case-1-f)
+ "error foo catched"))
+ (should (= (comp-tests-catch-f
+ (lambda () (throw 'foo 3)))
+ 3))
+ (should (= (catch 'foo
+ (comp-tests-throw-f 3)))))
+
+(comp-deftest gc ()
+ "Try to do some longer computation to let the gc kick in."
+ (dotimes (_ 100000)
+ (comp-tests-cons-cdr-f 3))
+ (should (= (comp-tests-cons-cdr-f 3) 3)))
+
+(comp-deftest buffer ()
+ (should (string= (comp-tests-buff0-f) "foo")))
+
+(comp-deftest lambda-return ()
+ (let ((f (comp-tests-lambda-return-f)))
+ (should (subr-native-elisp-p f))
+ (should (= (funcall f 3) 4))))
+
+(comp-deftest recursive ()
+ (should (= (comp-tests-fib-f 10) 55)))
+
+(comp-deftest macro ()
+ "Just check we can define macros"
+ (should (macrop (symbol-function 'comp-tests-macro-m))))
+
+(comp-deftest string-trim ()
+ (should (string= (comp-tests-string-trim-f "dsaf ") "dsaf")))
+
+(comp-deftest trampoline-removal ()
+ ;; This tests that we can can call primitives with no dedicated bytecode.
+ ;; At speed >= 2 the trampoline will not be used.
+ (should (hash-table-p (comp-tests-trampoline-removal-f))))
+
+(comp-deftest signal ()
+ (should (equal (condition-case err
+ (comp-tests-signal-f)
+ (t err))
+ '(foo . t))))
+
+(comp-deftest func-call-removal ()
+ ;; See `comp-propagate-insn' `comp-function-call-remove'.
+ (should (= (comp-tests-func-call-removal-f) 1)))
+
+(comp-deftest doc ()
+ (should (string= (documentation #'comp-tests-doc-f)
+ "A nice docstring"))
+ ;; Check a preloaded function, we can't use `comp-tests-doc-f' now
+ ;; as this is loaded manually with no .elc.
+ (should (string-match "\\.*.elc\\'" (symbol-file #'error))))
+
+(comp-deftest interactive-form ()
+ (should (equal (interactive-form #'comp-test-interactive-form0-f)
+ '(interactive "D")))
+ (should (equal (interactive-form #'comp-test-interactive-form1-f)
+ '(interactive '(1 2))))
+ (should (equal (interactive-form #'comp-test-interactive-form2-f)
+ '(interactive nil)))
+ (should (cl-every #'commandp '(comp-test-interactive-form0-f
+ comp-test-interactive-form1-f
+ comp-test-interactive-form2-f)))
+ (should-not (commandp #'comp-tests-doc-f)))
+
+(comp-deftest free-fun ()
+ "Check we are able to compile a single function."
+ (eval '(defun comp-tests-free-fun-f ()
+ "Some doc."
+ (interactive)
+ 3)
+ t)
+ (native-compile #'comp-tests-free-fun-f)
+
+ (should (subr-native-elisp-p (symbol-function #'comp-tests-free-fun-f)))
+ (should (= (comp-tests-free-fun-f) 3))
+ (should (string= (documentation #'comp-tests-free-fun-f)
+ "Some doc."))
+ (should (commandp #'comp-tests-free-fun-f))
+ (should (equal (interactive-form #'comp-tests-free-fun-f)
+ '(interactive))))
+
+(comp-deftest free-fun-silly-name ()
+ "Check we are able to compile a single function."
+ (eval '(defun comp-tests/free\fun-f ()) t)
+ (native-compile #'comp-tests/free\fun-f)
+ (should (subr-native-elisp-p (symbol-function #'comp-tests/free\fun-f))))
+
+(comp-deftest bug-40187 ()
+ "Check function name shadowing.
+https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-03/msg00914.html."
+ (should (eq (comp-test-40187-1-f) 'foo))
+ (should (eq (comp-test-40187-2-f) 'bar)))
+
+(comp-deftest speed--1 ()
+ "Check that at speed -1 we do not native compile."
+ (should (= (comp-test-speed--1-f) 3))
+ (should-not (subr-native-elisp-p (symbol-function #'comp-test-speed--1-f))))
+
+(comp-deftest bug-42360 ()
+ "<https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-07/msg00418.html>."
+ (should (string= (comp-test-42360-f "Nel mezzo del " 18 0 32 "yyy" nil)
+ "Nel mezzo del yyy")))
+
+(comp-deftest bug-44968 ()
+ "<https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-11/msg02357.html>"
+ (comp-test-44968-f "/tmp/test/foo" "/tmp"))
+
+(comp-deftest bug-45342 ()
+ "Preserve multibyte immediate strings.
+<https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-12/msg01771.html>"
+ (should (string= " ➊" (comp-test-45342-f 1))))
+
+(comp-deftest assume-double-neg ()
+ "In fwprop assumtions (not (not (member x))) /= (member x)."
+ (should-not (comp-test-assume-double-neg-f "bar" "foo")))
+
+(comp-deftest assume-in-loop-1 ()
+ "Broken call args assumptions lead to infinite loop."
+ (should (equal (comp-test-assume-in-loop-1-f "cd") '("cd"))))
+
+(comp-deftest bug-45376-1 ()
+ "<https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-12/msg01883.html>"
+ (should (equal (comp-test-45376-1-f) '(1 0))))
+
+(comp-deftest bug-45376-2 ()
+ "<https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-12/msg01883.html>"
+ (should (equal (comp-test-45376-2-f) '(0 2 1 0 1 0 1 0 0 0 0 0))))
+
+(defvar comp-test-primitive-advice)
+(comp-deftest primitive-advice ()
+ "Test effectiveness of primitive advicing."
+ (let (comp-test-primitive-advice
+ (f (lambda (&rest args)
+ (setq comp-test-primitive-advice args))))
+ (advice-add #'+ :before f)
+ (unwind-protect
+ (progn
+ (should (= (comp-test-primitive-advice-f 3 4) 7))
+ (should (equal comp-test-primitive-advice '(3 4))))
+ (advice-remove #'+ f))))
+
+(defvar comp-test-primitive-redefine-args)
+(comp-deftest primitive-redefine ()
+ "Test effectiveness of primitive redefinition."
+ (cl-letf ((comp-test-primitive-redefine-args nil)
+ ((symbol-function #'-)
+ (lambda (&rest args)
+ (setq comp-test-primitive-redefine-args args)
+ 'xxx)))
+ (should (eq (comp-test-primitive-redefine-f 10 2) 'xxx))
+ (should (equal comp-test-primitive-redefine-args '(10 2)))))
+
+(comp-deftest compile-forms ()
+ "Verify lambda form native compilation."
+ (should-error (native-compile '(+ 1 foo)))
+ (let ((lexical-binding t)
+ (f (native-compile '(lambda (x) (1+ x)))))
+ (should (subr-native-elisp-p f))
+ (should (= (funcall f 2) 3)))
+ (let* ((lexical-binding nil)
+ (f (native-compile '(lambda (x) (1+ x)))))
+ (should (subr-native-elisp-p f))
+ (should (= (funcall f 2) 3))))
+
+(comp-deftest comp-test-defsubst ()
+ ;; Bug#42664, Bug#43280, Bug#44209.
+ (should-not (subr-native-elisp-p (symbol-function #'comp-test-defsubst-f))))
+
+(comp-deftest primitive-redefine-compile-44221 ()
+ "Test the compiler still works while primitives are redefined (bug#44221)."
+ (cl-letf (((symbol-function #'delete-region)
+ (lambda (_ _))))
+ (should (subr-native-elisp-p
+ (native-compile
+ '(lambda ()
+ (delete-region (point-min) (point-max))))))))
+
+(comp-deftest and-3 ()
+ (should (= (comp-test-and-3-f t) 2))
+ (should (null (comp-test-and-3-f '(1 2)))))
+
+(comp-deftest copy-insn ()
+ (should (equal (comp-test-copy-insn-f '(1 2 3 (4 5 6)))
+ '(1 2 3 (4 5 6))))
+ (should (null (comp-test-copy-insn-f nil))))
+
+(comp-deftest cond-rw-1 ()
+ "Check cond-rw does not break target blocks with multiple predecessor."
+ (should (null (comp-test-cond-rw-1-2-f))))
+
+(comp-deftest not-cons-1 ()
+ (should-not (comp-test-not-cons-f nil)))
+
+(comp-deftest 45576-1 ()
+ "Functionp satisfies also symbols.
+<https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-01/msg00029.html>."
+ (should (eq (comp-test-45576-f) 'eval)))
+
+(comp-deftest 45635-1 ()
+ "<https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-01/msg00158.html>."
+ (should (string= (comp-test-45635-f :height 180 :family "PragmataPro Liga")
+ "PragmataPro Liga")))
+
+(comp-deftest 45603-1 ()
+ "<https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-12/msg01994.html>"
+ (load (native-compile (concat comp-test-directory "comp-test-45603.el")))
+ (should (fboundp #'comp-test-45603--file-local-name)))
+
+(comp-deftest 46670-1 ()
+ "<https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-02/msg01413.html>"
+ (should (string= (comp-test-46670-2-f "foo") "foo"))
+ (should (equal (subr-type (symbol-function #'comp-test-46670-2-f))
+ '(function (t) t))))
+
+(comp-deftest 46824-1 ()
+ "<https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-02/msg01949.html>"
+ (should (equal (comp-test-46824-1-f) nil)))
+
+(comp-deftest comp-test-47868-1 ()
+ "Verify string hash consing strategy.
+
+<https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-04/msg00921.html>"
+ (should-not (equal-including-properties (comp-test-47868-1-f)
+ (comp-test-47868-2-f)))
+ (should (eq (comp-test-47868-1-f) (comp-test-47868-3-f)))
+ (should (eq (comp-test-47868-2-f) (comp-test-47868-4-f))))
+
+
+;;;;;;;;;;;;;;;;;;;;;
+;; Tromey's tests. ;;
+;;;;;;;;;;;;;;;;;;;;;
+
+(comp-deftest consp ()
+ (should-not (comp-test-consp 23))
+ (should-not (comp-test-consp nil))
+ (should (comp-test-consp '(1 . 2))))
+
+(comp-deftest listp ()
+ (should-not (comp-test-listp 23))
+ (should (comp-test-listp nil))
+ (should (comp-test-listp '(1 . 2))))
+
+(comp-deftest stringp ()
+ (should-not (comp-test-stringp 23))
+ (should-not (comp-test-stringp nil))
+ (should (comp-test-stringp "hi")))
+
+(comp-deftest symbolp ()
+ (should-not (comp-test-symbolp 23))
+ (should-not (comp-test-symbolp "hi"))
+ (should (comp-test-symbolp 'whatever)))
+
+(comp-deftest integerp ()
+ (should (comp-test-integerp 23))
+ (should-not (comp-test-integerp 57.5))
+ (should-not (comp-test-integerp "hi"))
+ (should-not (comp-test-integerp 'whatever)))
+
+(comp-deftest numberp ()
+ (should (comp-test-numberp 23))
+ (should (comp-test-numberp 57.5))
+ (should-not (comp-test-numberp "hi"))
+ (should-not (comp-test-numberp 'whatever)))
+
+(comp-deftest add1 ()
+ (should (eq (comp-test-add1 23) 24))
+ (should (eq (comp-test-add1 -17) -16))
+ (should (eql (comp-test-add1 1.0) 2.0))
+ (should-error (comp-test-add1 nil)
+ :type 'wrong-type-argument))
+
+(comp-deftest sub1 ()
+ (should (eq (comp-test-sub1 23) 22))
+ (should (eq (comp-test-sub1 -17) -18))
+ (should (eql (comp-test-sub1 1.0) 0.0))
+ (should-error (comp-test-sub1 nil)
+ :type 'wrong-type-argument))
+
+(comp-deftest negate ()
+ (should (eq (comp-test-negate 23) -23))
+ (should (eq (comp-test-negate -17) 17))
+ (should (eql (comp-test-negate 1.0) -1.0))
+ (should-error (comp-test-negate nil)
+ :type 'wrong-type-argument))
+
+(comp-deftest not ()
+ (should (eq (comp-test-not 23) nil))
+ (should (eq (comp-test-not nil) t))
+ (should (eq (comp-test-not t) nil)))
+
+(comp-deftest bobp-and-eobp ()
+ (with-temp-buffer
+ (should (comp-test-bobp))
+ (should (comp-test-eobp))
+ (insert "hi")
+ (goto-char (point-min))
+ (should (eq (comp-test-point-min) (point-min)))
+ (should (eq (comp-test-point) (point-min)))
+ (should (comp-test-bobp))
+ (should-not (comp-test-eobp))
+ (goto-char (point-max))
+ (should (eq (comp-test-point-max) (point-max)))
+ (should (eq (comp-test-point) (point-max)))
+ (should-not (comp-test-bobp))
+ (should (comp-test-eobp))))
+
+(comp-deftest car-cdr ()
+ (let ((pair '(1 . b)))
+ (should (eq (comp-test-car pair) 1))
+ (should (eq (comp-test-car nil) nil))
+ (should-error (comp-test-car 23)
+ :type 'wrong-type-argument)
+ (should (eq (comp-test-cdr pair) 'b))
+ (should (eq (comp-test-cdr nil) nil))
+ (should-error (comp-test-cdr 23)
+ :type 'wrong-type-argument)))
+
+(comp-deftest car-cdr-safe ()
+ (let ((pair '(1 . b)))
+ (should (eq (comp-test-car-safe pair) 1))
+ (should (eq (comp-test-car-safe nil) nil))
+ (should (eq (comp-test-car-safe 23) nil))
+ (should (eq (comp-test-cdr-safe pair) 'b))
+ (should (eq (comp-test-cdr-safe nil) nil))
+ (should (eq (comp-test-cdr-safe 23) nil))))
+
+(comp-deftest eq ()
+ (should (comp-test-eq 'a 'a))
+ (should (comp-test-eq 5 5))
+ (should-not (comp-test-eq 'a 'b)))
+
+(comp-deftest if ()
+ (should (eq (comp-test-if 'a 'b) 'a))
+ (should (eq (comp-test-if 0 23) 0))
+ (should (eq (comp-test-if nil 'b) 'b)))
+
+(comp-deftest and ()
+ (should (eq (comp-test-and 'a 'b) 'b))
+ (should (eq (comp-test-and 0 23) 23))
+ (should (eq (comp-test-and nil 'b) nil)))
+
+(comp-deftest or ()
+ (should (eq (comp-test-or 'a 'b) 'a))
+ (should (eq (comp-test-or 0 23) 0))
+ (should (eq (comp-test-or nil 'b) 'b)))
+
+(comp-deftest save-excursion ()
+ (with-temp-buffer
+ (comp-test-save-excursion)
+ (should (eq (point) (point-min)))
+ (should (eq (comp-test-current-buffer) (current-buffer)))))
+
+(comp-deftest > ()
+ (should (eq (comp-test-> 0 23) nil))
+ (should (eq (comp-test-> 23 0) t)))
+
+(comp-deftest catch ()
+ (should (eq (comp-test-catch 0 1 2 3 4) nil))
+ (should (eq (comp-test-catch 20 21 22 23 24 25 26 27 28) 24)))
+
+(comp-deftest memq ()
+ (should (equal (comp-test-memq 0 '(5 4 3 2 1 0)) '(0)))
+ (should (eq (comp-test-memq 72 '(5 4 3 2 1 0)) nil)))
+
+(comp-deftest listN ()
+ (should (equal (comp-test-listN 57)
+ '(57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57))))
+
+(comp-deftest concatN ()
+ (should (equal (comp-test-concatN "x") "xxxxxx")))
+
+(comp-deftest opt-rest ()
+ (should (equal (comp-test-opt-rest 1) '(1 nil nil)))
+ (should (equal (comp-test-opt-rest 1 2) '(1 2 nil)))
+ (should (equal (comp-test-opt-rest 1 2 3) '(1 2 (3))))
+ (should (equal (comp-test-opt-rest 1 2 56 57 58)
+ '(1 2 (56 57 58)))))
+
+(comp-deftest opt ()
+ (should (equal (comp-test-opt 23) '(23)))
+ (should (equal (comp-test-opt 23 24) '(23 . 24)))
+ (should-error (comp-test-opt)
+ :type 'wrong-number-of-arguments)
+ (should-error (comp-test-opt nil 24 97)
+ :type 'wrong-number-of-arguments))
+
+(comp-deftest unwind-protect ()
+ (comp-test-unwind-protect 'ignore)
+ (should (eq comp-test-up-val 999))
+ (condition-case nil
+ (comp-test-unwind-protect (lambda () (error "HI")))
+ (error
+ nil))
+ (should (eq comp-test-up-val 999)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Tests for dynamic scope. ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(comp-deftest dynamic-ffuncall ()
+ "Test calling convention for dynamic binding."
+
+ (should (equal (comp-tests-ffuncall-callee-dyn-f 1 2)
+ '(1 2)))
+
+ (should (equal (comp-tests-ffuncall-callee-opt-dyn-f 1 2 3 4)
+ '(1 2 3 4)))
+ (should (equal (comp-tests-ffuncall-callee-opt-dyn-f 1 2 3)
+ '(1 2 3 nil)))
+ (should (equal (comp-tests-ffuncall-callee-opt-dyn-f 1 2)
+ '(1 2 nil nil)))
+
+ (should (equal (comp-tests-ffuncall-callee-rest-dyn-f 1 2)
+ '(1 2 nil)))
+ (should (equal (comp-tests-ffuncall-callee-rest-dyn-f 1 2 3)
+ '(1 2 (3))))
+ (should (equal (comp-tests-ffuncall-callee-rest-dyn-f 1 2 3 4)
+ '(1 2 (3 4))))
+
+ (should (equal (comp-tests-ffuncall-callee-opt-rest-dyn-f 1 2)
+ '(1 2 nil nil)))
+ (should (equal (comp-tests-ffuncall-callee-opt-rest-dyn-f 1 2 3)
+ '(1 2 3 nil)))
+ (should (equal (comp-tests-ffuncall-callee-opt-rest-dyn-f 1 2 3 4)
+ '(1 2 3 (4)))))
+
+(comp-deftest dynamic-arity ()
+ "Test func-arity on dynamic scope functions."
+ (should (equal '(2 . 2)
+ (func-arity #'comp-tests-ffuncall-callee-dyn-f)))
+ (should (equal '(2 . 4)
+ (func-arity #'comp-tests-ffuncall-callee-opt-dyn-f)))
+ (should (equal '(2 . many)
+ (func-arity #'comp-tests-ffuncall-callee-rest-dyn-f)))
+ (should (equal '(2 . many)
+ (func-arity #'comp-tests-ffuncall-callee-opt-rest-dyn-f))))
+
+(comp-deftest dynamic-help-arglist ()
+ "Test `help-function-arglist' works on lisp/d (bug#42572)."
+ (should (equal (help-function-arglist
+ (symbol-function #'comp-tests-ffuncall-callee-opt-rest-dyn-f)
+ t)
+ '(a b &optional c &rest d))))
+
+(comp-deftest cl-macro-exp ()
+ "Verify CL macro expansion (bug#42088)."
+ (should (equal (comp-tests-cl-macro-exp-f) '(a b))))
+
+(comp-deftest cl-uninterned-arg-parse-f ()
+ "Verify the parsing of a lambda list with uninterned symbols (bug#42120)."
+ (should (equal (comp-tests-cl-uninterned-arg-parse-f 1 2)
+ '(1 2))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Middle-end specific tests. ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun comp-tests-mentioned-p-1 (x insn)
+ (cl-loop for y in insn
+ when (cond
+ ((consp y) (comp-tests-mentioned-p x y))
+ ((and (comp-mvar-p y) (comp-cstr-imm-vld-p y))
+ (equal (comp-cstr-imm y) x))
+ (t (equal x y)))
+ return t))
+
+(defun comp-tests-mentioned-p (x insn)
+ "Check if X is actively mentioned in INSN."
+ (unless (eq (car-safe insn)
+ 'comment)
+ (comp-tests-mentioned-p-1 x insn)))
+
+(defun comp-tests-map-checker (func-name checker)
+ "Apply CHECKER to each insn of FUNC-NAME.
+Return a list of results."
+ (cl-loop
+ with func-c-name = (comp-c-func-name (or func-name 'anonymous-lambda) "F" t)
+ with f = (gethash func-c-name (comp-ctxt-funcs-h comp-ctxt))
+ for bb being each hash-value of (comp-func-blocks f)
+ nconc
+ (cl-loop
+ for insn in (comp-block-insns bb)
+ collect (funcall checker insn))))
+
+(defun comp-tests-tco-checker (_)
+ "Check that inside `comp-tests-tco-f' we have no recursion."
+ (should
+ (cl-notany
+ #'identity
+ (comp-tests-map-checker
+ 'comp-tests-tco-f
+ (lambda (insn)
+ (or (comp-tests-mentioned-p 'comp-tests-tco-f insn)
+ (comp-tests-mentioned-p (comp-c-func-name 'comp-tests-tco-f "F" t)
+ insn)))))))
+
+(comp-deftest tco ()
+ "Check for tail recursion elimination."
+ (let ((comp-speed 3)
+ ;; Disable ipa-pure otherwise `comp-tests-tco-f' gets
+ ;; optimized-out.
+ (comp-disabled-passes '(comp-ipa-pure))
+ (comp-post-pass-hooks '((comp-tco comp-tests-tco-checker)
+ (comp-final comp-tests-tco-checker))))
+ (eval '(defun comp-tests-tco-f (a b count)
+ (if (= count 0)
+ b
+ (comp-tests-tco-f (+ a b) a (- count 1))))
+ t)
+ (native-compile #'comp-tests-tco-f)
+ (should (subr-native-elisp-p (symbol-function #'comp-tests-tco-f)))
+ (should (= (comp-tests-tco-f 1 0 10) 55))))
+
+(defun comp-tests-fw-prop-checker-1 (_)
+ "Check that inside `comp-tests-fw-prop-f' `concat' and `length' are folded."
+ (should
+ (cl-notany
+ #'identity
+ (comp-tests-map-checker
+ 'comp-tests-fw-prop-1-f
+ (lambda (insn)
+ (or (comp-tests-mentioned-p 'concat insn)
+ (comp-tests-mentioned-p 'length insn)))))))
+
+(comp-deftest fw-prop-1 ()
+ "Some tests for forward propagation."
+ (let ((comp-speed 2)
+ (comp-post-pass-hooks '((comp-final comp-tests-fw-prop-checker-1))))
+ (eval '(defun comp-tests-fw-prop-1-f ()
+ (let* ((a "xxx")
+ (b "yyy")
+ (c (concat a b))) ; <= has to optimize
+ (length c))) ; <= has to optimize
+ t)
+ (native-compile #'comp-tests-fw-prop-1-f)
+ (should (subr-native-elisp-p (symbol-function #'comp-tests-fw-prop-1-f)))
+ (should (= (comp-tests-fw-prop-1-f) 6))))
+
+(defun comp-tests-check-ret-type-spec (func-form ret-type)
+ (let ((lexical-binding t)
+ (comp-speed 2)
+ (f-name (cl-second func-form)))
+ (eval func-form t)
+ (native-compile f-name)
+ (should (equal (cl-third (subr-type (symbol-function f-name)))
+ ret-type))))
+
+(cl-eval-when (compile eval load)
+ (defconst comp-tests-type-spec-tests
+ `(
+ ;; 1
+ ((defun comp-tests-ret-type-spec-f (x)
+ x)
+ t)
+
+ ;; 2
+ ((defun comp-tests-ret-type-spec-f ()
+ 1)
+ (integer 1 1))
+
+ ;; 3
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if x 1 3))
+ (or (integer 1 1) (integer 3 3)))
+
+ ;; 4
+ ((defun comp-tests-ret-type-spec-f (x)
+ (let (y)
+ (if x
+ (setf y 1)
+ (setf y 2))
+ y))
+ (integer 1 2))
+
+ ;; 5
+ ((defun comp-tests-ret-type-spec-f (x)
+ (let (y)
+ (if x
+ (setf y 1)
+ (setf y 3))
+ y))
+ (or (integer 1 1) (integer 3 3)))
+
+ ;; 6
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if x
+ (list x)
+ 3))
+ (or cons (integer 3 3)))
+
+ ;; 7
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if x
+ 'foo
+ 3))
+ (or (member foo) (integer 3 3)))
+
+ ;; 8
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (eq x 3)
+ x
+ 'foo))
+ (or (member foo) (integer 3 3)))
+
+ ;; 9
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (eq 3 x)
+ x
+ 'foo))
+ (or (member foo) (integer 3 3)))
+
+ ;; 10
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (eql x 3)
+ x
+ 'foo))
+ (or (member foo) (integer 3 3)))
+
+ ;; 11
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (eql 3 x)
+ x
+ 'foo))
+ (or (member foo) (integer 3 3)))
+
+ ;; 12
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (eql x 3)
+ 'foo
+ x))
+ (not (integer 3 3)))
+
+ ;; 13
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (if (= x y)
+ x
+ 'foo))
+ (or (member foo) marker number))
+
+ ;; 14
+ ((defun comp-tests-ret-type-spec-f (x)
+ (comp-hint-fixnum x))
+ (integer ,most-negative-fixnum ,most-positive-fixnum))
+
+ ;; 15
+ ((defun comp-tests-ret-type-spec-f (x)
+ (comp-hint-cons x))
+ cons)
+
+ ;; 16
+ ((defun comp-tests-ret-type-spec-f (x)
+ (let (y)
+ (when x
+ (setf y 4))
+ y))
+ (or null (integer 4 4)))
+
+ ;; 17
+ ((defun comp-tests-ret-type-spec-f ()
+ (let (x
+ (y 3))
+ (setf x y)
+ y))
+ (integer 3 3))
+
+ ;; 18
+ ((defun comp-tests-ret-type-spec-f (x)
+ (let ((y 3))
+ (when x
+ (setf y x))
+ y))
+ t)
+
+ ;; 19
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (eq x y))
+ boolean)
+
+ ;; 20
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when x
+ 'foo))
+ (or (member foo) null))
+
+ ;; 21
+ ((defun comp-tests-ret-type-spec-f (x)
+ (unless x
+ 'foo))
+ (or (member foo) null))
+
+ ;; 22
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (> x 3)
+ x))
+ (or null float (integer 4 *)))
+
+ ;; 23
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (>= x 3)
+ x))
+ (or null float (integer 3 *)))
+
+ ;; 24
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (< x 3)
+ x))
+ (or null float (integer * 2)))
+
+ ;; 25
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (<= x 3)
+ x))
+ (or null float (integer * 3)))
+
+ ;; 26
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (> 3 x)
+ x))
+ (or null float (integer * 2)))
+
+ ;; 27
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (>= 3 x)
+ x))
+ (or null float (integer * 3)))
+
+ ;; 28
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (< 3 x)
+ x))
+ (or null float (integer 4 *)))
+
+ ;; 29
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (<= 3 x)
+ x))
+ (or null float (integer 3 *)))
+
+ ;; 30
+ ((defun comp-tests-ret-type-spec-f (x)
+ (let ((y 3))
+ (when (> x y)
+ x)))
+ (or null float (integer 4 *)))
+
+ ;; 31
+ ((defun comp-tests-ret-type-spec-f (x)
+ (let ((y 3))
+ (when (> y x)
+ x)))
+ (or null float (integer * 2)))
+
+ ;; 32
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (and (> x 3)
+ (< x 10))
+ x))
+ (or null float (integer 4 9)))
+
+ ;; 33
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (or (> x 3)
+ (< x 10))
+ x))
+ (or null float integer))
+
+ ;; 34
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (or (< x 3)
+ (> x 10))
+ x))
+ (or null float (integer * 2) (integer 11 *)))
+
+ ;; 35 No float range support.
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (> x 1.0)
+ x))
+ (or null marker number))
+
+ ;; 36
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (when (and (> x 3)
+ (> y 2))
+ (+ x y)))
+ (or null float (integer 7 *)))
+
+ ;; 37
+ ;; SBCL: (OR REAL NULL)
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (when (and (<= x 3)
+ (<= y 2))
+ (+ x y)))
+ (or null float (integer * 5)))
+
+ ;; 38
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (when (and (< 1 x 5)
+ (< 1 y 5))
+ (+ x y)))
+ (or null float (integer 4 8)))
+
+ ;; 39
+ ;; SBCL gives: (OR REAL NULL)
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (when (and (<= 1 x 10)
+ (<= 2 y 3))
+ (+ x y)))
+ (or null float (integer 3 13)))
+
+ ;; 40
+ ;; SBCL: (OR REAL NULL)
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (when (and (<= 1 x 10)
+ (<= 2 y 3))
+ (- x y)))
+ (or null float (integer -2 8)))
+
+ ;; 41
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (when (and (<= 1 x)
+ (<= 2 y 3))
+ (- x y)))
+ (or null float (integer -2 *)))
+
+ ;; 42
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (when (and (<= 1 x 10)
+ (<= 2 y))
+ (- x y)))
+ (or null float (integer * 8)))
+
+ ;; 43
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (when (and (<= x 10)
+ (<= 2 y))
+ (- x y)))
+ (or null float (integer * 8)))
+
+ ;; 44
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (when (and (<= x 10)
+ (<= y 3))
+ (- x y)))
+ (or null float integer))
+
+ ;; 45
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (when (and (<= 2 x)
+ (<= 3 y))
+ (- x y)))
+ (or null float integer))
+
+ ;; 46
+ ;; SBCL: (OR (RATIONAL (6) (30)) (SINGLE-FLOAT 6.0 30.0)
+ ;; (DOUBLE-FLOAT 6.0d0 30.0d0) NULL)
+ ((defun comp-tests-ret-type-spec-f (x y z i j k)
+ (when (and (< 1 x 5)
+ (< 1 y 5)
+ (< 1 z 5)
+ (< 1 i 5)
+ (< 1 j 5)
+ (< 1 k 5))
+ (+ x y z i j k)))
+ (or null float (integer 12 24)))
+
+ ;; 47
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (<= 1 x 5)
+ (1+ x)))
+ (or null float (integer 2 6)))
+
+ ;;48
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (<= 1 x 5)
+ (1- x)))
+ (or null float (integer 0 4)))
+
+ ;; 49
+ ((defun comp-tests-ret-type-spec-f ()
+ (error "foo"))
+ nil)
+
+ ;; 50
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (stringp x)
+ x
+ 'bar))
+ (or (member bar) string))
+
+ ;; 51
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (stringp x)
+ 'bar
+ x))
+ (not string))
+
+ ;; 52
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (integerp x)
+ x
+ 'bar))
+ (or (member bar) integer))
+
+ ;; 53
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (integerp x)
+ x))
+ (or null integer))
+
+ ;; 54
+ ((defun comp-tests-ret-type-spec-f (x)
+ (unless (symbolp x)
+ x))
+ t)
+
+ ;; 55
+ ((defun comp-tests-ret-type-spec-f (x)
+ (unless (integerp x)
+ x))
+ (not integer))
+
+ ;; 56
+ ((defun comp-tests-ret-type-spec-f (x)
+ (cl-ecase x
+ (1 (message "one"))
+ (5 (message "five")))
+ x)
+ t
+ ;; FIXME improve `comp-cond-cstrs-target-mvar' to cross block
+ ;; boundary if necessary as this should return:
+ ;; (or (integer 1 1) (integer 5 5))
+ )
+
+ ;; 57
+ ((defun comp-tests-ret-type-spec-f (x)
+ (unless (or (eq x 'foo)
+ (eql x 3))
+ (error "Not foo or 3"))
+ x)
+ (or (member foo) (integer 3 3)))
+
+ ;;58
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (if (and (natnump x)
+ (natnump y)
+ (<= x y))
+ x
+ (error "")))
+ (integer 0 *))
+
+ ;; 59
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (if (and (>= x 3)
+ (<= y 10)
+ (<= x y))
+ x
+ (error "")))
+ (or float (integer 3 10)))
+
+ ;; 60
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (if (and (<= x 10)
+ (>= y 3)
+ (>= x y))
+ x
+ (error "")))
+ (or float (integer 3 10)))
+
+ ;; 61
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (= x 1.0)
+ x
+ (error "")))
+ (or (member 1.0) (integer 1 1)))
+
+ ;; 62
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (= x 1.0)
+ x
+ (error "")))
+ (or (member 1.0) (integer 1 1)))
+
+ ;; 63
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (= x 1.1)
+ x
+ (error "")))
+ (member 1.1))
+
+ ;; 64
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (= x 1)
+ x
+ (error "")))
+ (or (member 1.0) (integer 1 1)))
+
+ ;; 65
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (= x 1)
+ x
+ (error "")))
+ (or (member 1.0) (integer 1 1)))
+
+ ;; 66
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (eql x 0.0)
+ x
+ (error "")))
+ float)
+
+ ;; 67
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (equal x '(1 2 3))
+ x
+ (error "")))
+ cons)
+
+ ;; 68
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (and (floatp x)
+ (= x 1))
+ x
+ (error "")))
+ ;; Conservative (see cstr relax in `comp-cstr-=').
+ (or (member 1.0) (integer 1 1)))
+
+ ;; 69
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (and (integer x)
+ (= x 1))
+ x
+ (error "")))
+ ;; Conservative (see cstr relax in `comp-cstr-=').
+ (or (member 1.0) (integer 1 1)))
+
+ ;; 70
+ ((defun comp-tests-ret-type-spec-f (x y)
+ (if (and (floatp x)
+ (integerp y)
+ (= x y))
+ x
+ (error "")))
+ (or float integer))
+
+ ;; 71
+ ((defun comp-tests-ret-type-spec-f (x)
+ (if (= x 0.0)
+ x
+ (error "")))
+ (or (member -0.0 0.0) (integer 0 0)))
+
+ ;; 72
+ ((defun comp-tests-ret-type-spec-f (x)
+ (unless (= x 0.0)
+ (error ""))
+ (unless (eql x -0.0)
+ (error ""))
+ x)
+ float)
+
+ ;; 73
+ ((defun comp-tests-ret-type-spec-f (x)
+ (when (eql x 1.0)
+ (error ""))
+ x)
+ t)))
+
+ (defun comp-tests-define-type-spec-test (number x)
+ `(comp-deftest ,(intern (format "ret-type-spec-%d" number)) ()
+ ,(format "Type specifier test number %d." number)
+ (let ((comp-ctxt (make-comp-cstr-ctxt)))
+ (comp-tests-check-ret-type-spec ',(car x) ',(cadr x))))))
+
+(defmacro comp-tests-define-type-spec-tests ()
+ "Define all type specifier tests."
+ `(progn
+ ,@(cl-loop
+ for test in comp-tests-type-spec-tests
+ for n from 1
+ collect (comp-tests-define-type-spec-test n test))))
+
+(comp-tests-define-type-spec-tests)
+
+(defun comp-tests-pure-checker-1 (_)
+ "Check that inside `comp-tests-pure-caller-f' `comp-tests-pure-callee-f' is
+ folded."
+ (should
+ (cl-notany
+ #'identity
+ (comp-tests-map-checker
+ 'comp-tests-pure-caller-f
+ (lambda (insn)
+ (or (comp-tests-mentioned-p 'comp-tests-pure-callee-f insn)
+ (comp-tests-mentioned-p (comp-c-func-name
+ 'comp-tests-pure-callee-f "F" t)
+ insn)))))))
+
+(defun comp-tests-pure-checker-2 (_)
+ "Check that `comp-tests-pure-fibn-f' is folded."
+ (should
+ (cl-notany
+ #'identity
+ (comp-tests-map-checker
+ 'comp-tests-pure-fibn-entry-f
+ (lambda (insn)
+ (or (comp-tests-mentioned-p 'comp-tests-pure-fibn-f insn)
+ (comp-tests-mentioned-p (comp-c-func-name 'comp-tests-pure-fibn-f "F" t)
+ insn)))))))
+
+(comp-deftest pure ()
+ "Some tests for pure functions optimization."
+ (let ((comp-speed 3)
+ (comp-post-pass-hooks '((comp-final comp-tests-pure-checker-1
+ comp-tests-pure-checker-2))))
+ (load (native-compile (concat comp-test-directory "comp-test-pure.el")))
+
+ (should (subr-native-elisp-p (symbol-function #'comp-tests-pure-caller-f)))
+ (should (= (comp-tests-pure-caller-f) 4))
+
+ (should (subr-native-elisp-p (symbol-function #'comp-tests-pure-fibn-entry-f)))
+ (should (= (comp-tests-pure-fibn-entry-f) 6765))))
+
+(defvar comp-tests-cond-rw-checked-function nil
+ "Function to be checked.")
+(defun comp-tests-cond-rw-checker-val (_)
+ "Check we manage to propagate the correct return value."
+ (should
+ (cl-some
+ #'identity
+ (comp-tests-map-checker
+ comp-tests-cond-rw-checked-function
+ (lambda (insn)
+ (pcase insn
+ (`(return ,mvar)
+ (and (comp-cstr-imm-vld-p mvar)
+ (eql (comp-cstr-imm mvar) 123)))))))))
+
+(defvar comp-tests-cond-rw-expected-type nil
+ "Type to expect in `comp-tests-cond-rw-checker-type'.")
+(defun comp-tests-cond-rw-checker-type (_)
+ "Check we manage to propagate the correct return type."
+ (should
+ (cl-some
+ #'identity
+ (comp-tests-map-checker
+ comp-tests-cond-rw-checked-function
+ (lambda (insn)
+ (pcase insn
+ (`(return ,mvar)
+ (equal (comp-mvar-typeset mvar)
+ comp-tests-cond-rw-expected-type))))))))
+
+;;; comp-tests.el ends here