diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile.in | 2 | ||||
-rw-r--r-- | test/data/emacs-module/mod-test.c | 24 | ||||
-rw-r--r-- | test/src/emacs-module-tests.el | 40 |
3 files changed, 62 insertions, 4 deletions
diff --git a/test/Makefile.in b/test/Makefile.in index 7b8c967128f..0c24c48e60e 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -68,7 +68,7 @@ EMACS_EXTRAOPT= # Command line flags for Emacs. # Apparently MSYS bash would convert "-L :" to "-L ;" anyway, # but we might as well be explicit. -EMACSOPT = -batch --no-site-file --no-site-lisp -L "$(SEPCHAR)$(srcdir)" $(EMACS_EXTRAOPT) +EMACSOPT = -batch --no-site-file --no-site-lisp -module-assertions -L "$(SEPCHAR)$(srcdir)" $(EMACS_EXTRAOPT) # Prevent any settings in the user environment causing problems. unexport EMACSDATA EMACSDOC EMACSPATH GREP_OPTIONS diff --git a/test/data/emacs-module/mod-test.c b/test/data/emacs-module/mod-test.c index 309179d1501..fc29a0d6b9a 100644 --- a/test/data/emacs-module/mod-test.c +++ b/test/data/emacs-module/mod-test.c @@ -213,6 +213,28 @@ Fmod_test_vector_eq (emacs_env *env, ptrdiff_t nargs, emacs_value args[], return env->intern (env, "t"); } +static emacs_value invalid_stored_value; + +/* The next two functions perform a possibly-invalid operation: they + store a value in a static variable and load it. This causes + undefined behavior if the environment that the value was created + from is no longer live. The module assertions check for this + error. */ + +static emacs_value +Fmod_test_invalid_store (emacs_env *env, ptrdiff_t nargs, emacs_value *args, + void *data) +{ + return invalid_stored_value = env->make_integer (env, 123); +} + +static emacs_value +Fmod_test_invalid_load (emacs_env *env, ptrdiff_t nargs, emacs_value *args, + void *data) +{ + return invalid_stored_value; +} + /* Lisp utilities for easier readability (simple wrappers). */ @@ -260,6 +282,8 @@ emacs_module_init (struct emacs_runtime *ert) DEFUN ("mod-test-userptr-get", Fmod_test_userptr_get, 1, 1, NULL, NULL); DEFUN ("mod-test-vector-fill", Fmod_test_vector_fill, 2, 2, NULL, NULL); DEFUN ("mod-test-vector-eq", Fmod_test_vector_eq, 2, 2, NULL, NULL); + DEFUN ("mod-test-invalid-store", Fmod_test_invalid_store, 0, 0, NULL, NULL); + DEFUN ("mod-test-invalid-load", Fmod_test_invalid_load, 0, 0, NULL, NULL); #undef DEFUN diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el index 622bbadb3ef..99a853b17e0 100644 --- a/test/src/emacs-module-tests.el +++ b/test/src/emacs-module-tests.el @@ -19,9 +19,17 @@ (require 'ert) -(require 'mod-test - (expand-file-name "data/emacs-module/mod-test" - (getenv "EMACS_TEST_DIRECTORY"))) +(defconst mod-test-emacs + (expand-file-name invocation-name invocation-directory) + "File name of the Emacs binary currently running.") + +(eval-and-compile + (defconst mod-test-file + (substitute-in-file-name + "$EMACS_TEST_DIRECTORY/data/emacs-module/mod-test") + "File name of the module test file.")) + +(require 'mod-test mod-test-file) ;; ;; Basic tests. @@ -174,4 +182,30 @@ changes." (should (equal (help-function-arglist #'mod-test-sum) '(arg1 arg2)))) +(ert-deftest module--test-assertions () + "Check that -module-assertions work." + (skip-unless (file-executable-p mod-test-emacs)) + ;; This doesn’t yet cause undefined behavior. + (should (eq (mod-test-invalid-store) 123)) + (with-temp-buffer + (should (equal (call-process mod-test-emacs nil t nil + "-batch" "-Q" "-module-assertions" "-eval" + (prin1-to-string + `(progn + (require 'mod-test ,mod-test-file) + ;; Storing and reloading a local + ;; value causes undefined + ;; behavior, which should be + ;; detected by the module + ;; assertions. + (mod-test-invalid-store) + (mod-test-invalid-load)))) + ;; FIXME: This string is probably different on + ;; Windows and Linux. + "Abort trap: 6")) + (re-search-backward (rx bos "Emacs module assertion: " + "Emacs value not found in " + (+ digit) " values of " + (+ digit) " environments" ?\n eos)))) + ;;; emacs-module-tests.el ends here |