summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Makefile.in2
-rw-r--r--test/data/emacs-module/mod-test.c24
-rw-r--r--test/src/emacs-module-tests.el40
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