From 1e10761593613c885fdbe5130e708b16a331ddef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kochma=C5=84ski?= Date: Sun, 16 Nov 2025 11:03:48 +0100 Subject: [PATCH 1/2] tests: add a test for the recent regression --- src/tests/normal-tests/compiler.lsp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/tests/normal-tests/compiler.lsp b/src/tests/normal-tests/compiler.lsp index 253df5a2a..4f08600c6 100644 --- a/src/tests/normal-tests/compiler.lsp +++ b/src/tests/normal-tests/compiler.lsp @@ -2571,3 +2571,23 @@ (symbol-macrolet ((value -27)) (load-time-value (block b4 (woosh b4 value)))))))))) + +;;; Date 2025-11-16 +;;; URL: https://gitlab.com/embeddable-common-lisp/ecl/-/issues/802 +;;; Regression commit: 521e815158dc92e6b8af18d007808349764b5623 +;;; Reported by: Jan Moringen +;;; Description +;;; +;;; Regression in TAGBODY handling by the C compiler. +;;; +(deftest cmp.0110.tagbody-regression () + (is (eql 42 + (funcall (compile nil + '(lambda (&aux (always-nil nil)) + (block nil + (tagbody + :package + (when always-nil + (go :package)) + :symbol + (return 42))))))))) From 7c5471947dc260e245f89e7e7eaba35f1226c4d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kochma=C5=84ski?= Date: Mon, 17 Nov 2025 10:39:45 +0100 Subject: [PATCH 2/2] c2tagbody-body: fix a regression when processing intermediate tag In 521e815158dc92e6b8af18d007808349764b5623 I've introduced a regression where we did not bind the destination and exit label for intermediate forms. Fixes #802. --- src/cmp/cmpbackend-cxx/cmppass2-cont.lsp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/cmp/cmpbackend-cxx/cmppass2-cont.lsp b/src/cmp/cmpbackend-cxx/cmppass2-cont.lsp index cb8567f7b..6defe114a 100644 --- a/src/cmp/cmpbackend-cxx/cmppass2-cont.lsp +++ b/src/cmp/cmpbackend-cxx/cmppass2-cont.lsp @@ -91,15 +91,19 @@ (defun c2tagbody-body (body) ;;; INV: BODY is a list of tags and forms. We have processed the body ;;; so that the last element is always a form producing NIL. - (loop for (this-form next-form . rest) on body do + (loop for (this-form . rest) on body do (cond ((tag-p this-form) (wt-label (tag-jump this-form))) - ((tag-p next-form) - (with-exit-label (*exit* (tag-jump next-form)) - (let ((*destination* 'TRASH)) - (c2expr this-form)))) + ((endp rest) + ;; Last form, it is never a label! + (c2expr this-form)) (t - (c2expr this-form))))) + (let* ((next-form (first rest)) + (maybe-tag (when (tag-p next-form) + (tag-jump next-form)))) + (with-exit-label (*exit* maybe-tag) + (let ((*destination* 'TRASH)) + (c2expr this-form)))))))) (defun c2go (c1form tag nonlocal) (declare (ignore c1form))