From f616edb4ccce5b9d60e3ff42806bd2131989cd1e Mon Sep 17 00:00:00 2001
From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= <mattiase@acm.org>
Date: Mon, 25 Sep 2023 14:40:11 +0200
Subject: [PATCH] macroexp-parse-body: correct parsing of empty body
 (bug#66136)

* lisp/emacs-lisp/macroexp.el (macroexp-parse-body):
Return an empty body even when there are declarations present.
Previously, the last declaration was considered part of the body,
which is only correct if the input consists of a single string.

Reported by Jens Schmidt.
---
 lisp/emacs-lisp/macroexp.el | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index f96e0d74026..3ef924a5c73 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -525,12 +525,17 @@ definitions to shadow the loaded ones for use in file byte-compilation."
 (defun macroexp-parse-body (body)
   "Parse a function BODY into (DECLARATIONS . EXPS)."
   (let ((decls ()))
-    (while (and (cdr body)
-                (let ((e (car body)))
-                  (or (stringp e)
-                      (memq (car-safe e)
-                            '(:documentation declare interactive cl-declare)))))
-      (push (pop body) decls))
+    ;; If there is only a string literal with nothing following, we
+    ;; consider this to be part of the body (the return value) rather
+    ;; than a declaration at this point.
+    (unless (and (null (cdr body)) (stringp (car body)))
+      (while
+          (and body
+               (let ((e (car body)))
+                 (or (stringp e)
+                     (memq (car-safe e)
+                           '(:documentation declare interactive cl-declare)))))
+        (push (pop body) decls)))
     (cons (nreverse decls) body)))
 
 (defun macroexp-progn (exps)
-- 
2.39.5