Correctly eliminate duplicate cases in switch compilation
Fix code mistakes that prevented the correct elimination of duplicated cases when compiling a `cond' form to a switch bytecode, as in (cond ((eq x 'a) 1) ((eq x 'b) 2) ((eq x 'a) 3) ; should be elided ((eq x 'c) 4)) Sometimes, this caused the bytecode to use the wrong branch (bug#35770). * lisp/emacs-lisp/bytecomp.el (byte-compile-cond-vars): Return obj2 eval'ed. (byte-compile-cond-jump-table-info): Discard redundant condition. Use `obj2' as evaluated. Discard duplicated cases instead of failing the table generation. * test/lisp/emacs-lisp/bytecomp-tests.el (toplevel): Require subr-x. (byte-opt-testsuite-arith-data, bytecomp-test--switch-duplicates): Test.
This commit is contained in:
parent
457b024405
commit
68b374a62d
2 changed files with 60 additions and 8 deletions
|
@ -4091,8 +4091,8 @@ that suppresses all warnings during execution of BODY."
|
|||
;; and the other is a constant expression whose value can be
|
||||
;; compared with `eq' (with `macroexp-const-p').
|
||||
(or
|
||||
(and (symbolp obj1) (macroexp-const-p obj2) (cons obj1 obj2))
|
||||
(and (symbolp obj2) (macroexp-const-p obj1) (cons obj2 obj1))))
|
||||
(and (symbolp obj1) (macroexp-const-p obj2) (cons obj1 (eval obj2)))
|
||||
(and (symbolp obj2) (macroexp-const-p obj1) (cons obj2 (eval obj1)))))
|
||||
|
||||
(defconst byte-compile--default-val (cons nil nil) "A unique object.")
|
||||
|
||||
|
@ -4121,12 +4121,11 @@ Return a list of the form ((TEST . VAR) ((VALUE BODY) ...))"
|
|||
(unless prev-test
|
||||
(setq prev-test test))
|
||||
(if (and obj1 (memq test '(eq eql equal))
|
||||
(consp condition)
|
||||
(eq test prev-test)
|
||||
(eq obj1 prev-var)
|
||||
;; discard duplicate clauses
|
||||
(not (assq obj2 cases)))
|
||||
(push (list (if (consp obj2) (eval obj2) obj2) body) cases)
|
||||
(eq obj1 prev-var))
|
||||
;; discard duplicate clauses
|
||||
(unless (assoc obj2 cases test)
|
||||
(push (list obj2 body) cases))
|
||||
(if (and (macroexp-const-p condition) condition)
|
||||
(progn (push (list byte-compile--default-val
|
||||
(or body `(,condition)))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue