(car form))
(byte-optimize-body (cdr form) for-effect)))))
+(defun byte-opt--every (pred seq)
+ "Check whether PRED holds for every element of SEQ."
+ (while (and seq (funcall pred (car seq)))
+ (setq seq (cdr seq)))
+ (null seq))
+
+(defun byte-opt--return-p (form)
+ "Check whether evaluating FORM may return.
+If this function returns nil, then FORM never returns."
+ (unless (memq (car-safe form) '(throw signal error user-error))
+ (pcase form
+ (`(,(or 'let 'let*) ,bindings . ,body)
+ (and (byte-opt--every (lambda (binding)
+ (byte-opt--return-p
+ (if (cdr binding) (cadr binding) (car binding))))
+ bindings)
+ (byte-opt--every #'byte-opt--return-p body)))
+ (`(,(or 'progn 'prog1 'save-excursion 'save-restriction 'save-current-buffer) . ,exps)
+ (byte-opt--every #'byte-opt--return-p exps))
+ (`(if ,test ,then . ,else)
+ (and (byte-opt--return-p test)
+ (or (byte-opt--return-p then)
+ (byte-opt--every #'byte-opt--return-p else))))
+ (`(,(or 'and 'or) . ,exps)
+ (not (byte-opt--every (lambda (exp) (not (byte-opt--return-p exp))) exps)))
+ (`(while ,exp . ,exps)
+ (and (not (byte-compile-trueconstp exp))
+ (byte-opt--every #'byte-opt--return-p exps)))
+ ;; (`(cond . ,clauses) ...)
+ ;; (`(condition-case ,var ,exp . ,clauses) ...)
+ ;; (`(unwind-protect ,protected-expr :fun-body ,unwind-fun) ...)
+ ;; (`(catch ,tag . ,exps) ...)
+ ;; (`(internal-make-closure ,vars ,env . ,rest) ...)
+ ;; (`(setq ,var ,expr . ,more) ...)
+ ;; (`(defvar ,var . ,rest) ...)
+ (_ t))))
(defun byte-optimize-body (forms all-for-effect)
;; Optimize the cdr of a progn or implicit progn; all forms is a list of
(setq new (pop result)))
(when (or new (not fe))
(setq result (cons new result)))
- (setq rest (cdr rest)))
+ (setq rest (cdr rest))
+ (when (and rest (not (byte-opt--return-p new)))
+ (byte-compile-warn-x rest "Unreachable code")))
(nreverse result)))
\f