diff options
| author | Mattias EngdegÄrd <mattiase@acm.org> | 2023-07-25 12:16:30 +0200 |
|---|---|---|
| committer | Mattias EngdegÄrd <mattiase@acm.org> | 2023-07-26 17:34:03 +0200 |
| commit | 82f5f3b8a26249db0679bb7dc38c44352e8fbdf5 (patch) | |
| tree | 5890c3bec8dd65921695dd52949545cf21e92707 /src/bytecode.c | |
| parent | c50f6538cfc43d856b361347c945f6348c6f2dc9 (diff) | |
Provide backtrace for byte-ops aref and aset
Produce synthetic backtrace entries for `aref` and `aset` byte-ops
when the index is non-fixnum, or is out of range for vector or record
arguments (bug#64613).
* src/bytecode.c (exec_byte_code): Detect type and range errors
in-line for aref and aset.
* src/data.c (syms_of_data): Declare symbols Qaref and Qaset.
* test/lisp/emacs-lisp/bytecomp-tests.el
(bytecomp-tests--byte-op-error-cases): Add test cases.
Diffstat (limited to 'src/bytecode.c')
| -rw-r--r-- | src/bytecode.c | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/src/bytecode.c b/src/bytecode.c index 2eb53b0428a..c53ef678edd 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1115,14 +1115,24 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, { Lisp_Object idxval = POP; Lisp_Object arrayval = TOP; + if (!FIXNUMP (idxval)) + { + record_in_backtrace (Qaref, &TOP, 2); + wrong_type_argument (Qfixnump, idxval); + } ptrdiff_t size; - ptrdiff_t idx; if (((VECTORP (arrayval) && (size = ASIZE (arrayval), true)) - || (RECORDP (arrayval) && (size = PVSIZE (arrayval), true))) - && FIXNUMP (idxval) - && (idx = XFIXNUM (idxval), - idx >= 0 && idx < size)) - TOP = AREF (arrayval, idx); + || (RECORDP (arrayval) && (size = PVSIZE (arrayval), true)))) + { + ptrdiff_t idx = XFIXNUM (idxval); + if (idx >= 0 && idx < size) + TOP = AREF (arrayval, idx); + else + { + record_in_backtrace (Qaref, &TOP, 2); + args_out_of_range (arrayval, idxval); + } + } else TOP = Faref (arrayval, idxval); NEXT; @@ -1133,16 +1143,26 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, Lisp_Object newelt = POP; Lisp_Object idxval = POP; Lisp_Object arrayval = TOP; + if (!FIXNUMP (idxval)) + { + record_in_backtrace (Qaset, &TOP, 3); + wrong_type_argument (Qfixnump, idxval); + } ptrdiff_t size; - ptrdiff_t idx; if (((VECTORP (arrayval) && (size = ASIZE (arrayval), true)) - || (RECORDP (arrayval) && (size = PVSIZE (arrayval), true))) - && FIXNUMP (idxval) - && (idx = XFIXNUM (idxval), - idx >= 0 && idx < size)) + || (RECORDP (arrayval) && (size = PVSIZE (arrayval), true)))) { - ASET (arrayval, idx, newelt); - TOP = newelt; + ptrdiff_t idx = XFIXNUM (idxval); + if (idx >= 0 && idx < size) + { + ASET (arrayval, idx, newelt); + TOP = newelt; + } + else + { + record_in_backtrace (Qaset, &TOP, 3); + args_out_of_range (arrayval, idxval); + } } else TOP = Faset (arrayval, idxval, newelt); |
