Subject: bug#67883: closed (Re: bug#57957: bug#69872: 29.2; Async native compilation of seq.el test uses up resources and hangs)

From: [email-masked] (GNU bug Tracking System)
Date: Mon, 01 Apr 2024 20:48:02 +0000

Your bug report

#69872: 29.1.90; Native compiler hangs when compiling code with circular objects

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
69872: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69872
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#57957: bug#69872: 29.2; Async native compilation of seq.el test uses up resources and hangs
From: Andrea Corallo <[email-masked]>
To: Andrea Corallo <[email-masked]>
Cc: Lars Tveito <[email-masked]>, hokomo <[email-masked]>, [email-masked], Gerd Möllmann <[email-masked]>, [email-masked], Stefan Monnier <[email-masked]>, Lars Ingebrigtsen <[email-masked]>
Date: Mon, 01 Apr 2024 16:46:47 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

Andrea Corallo <[email-masked]> writes:

> Andrea Corallo <[email-masked]> writes:
>
>> Stefan Monnier <[email-masked]> writes:
>>
>>>> The question is of course also how much effort circular lists deserve in
>>>> the compiler.  From my point of view, not too much because they aren't
>>>> very useful, in code at least.  And dealing with them costs runtime.
>>>
>>> Circular data structures are perfectly normal in source code under
>>> a `quote` but the code itself should never be cyclic (so I think it
>>> would be OK to signal an error (and/or to inf-loop) when asked to
>>> compile a chunk of code that has a cycle).  So we *should* handle
>>> circular data structures correctly.
>>
>> I agree, Saturday I should have some time to look into this.
>
> A little time after... I finally managed to get to it, sorry for the
> delay.
>
> I've pushed into master c5de73a95a6, it fixes my reprodurer here and
> adds a test for this.
>
> If anyone could confirm this is fixed i'll be (extremely) happy to close
> this :)
>
> Thanks
>
>   Andrea

Right I'm closing this as I believe it's fixed, happy to re-open if it's
not the case.

Thanks!

  Andrea

Subject: 29.1.90; Native compiler hangs when compiling code with circular objects
From: hokomo <[email-masked]>
To: [email-masked]
Date: Mon, 18 Dec 2023 18:22:41 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Hello,

The Emacs Lisp native compiler goes into an infinite loop when 
compiling code that contains circular objects.

For example, put the following into a file and use M-x 
emacs-lisp-native-compile; it should hang:

  (defun test1 ()
    '#1=(1 2 3 . #1#))

It seems like this only happens for certain top-level forms, such 
as `defun' (which may be expected behavior, due to the way the 
file compiler processes top-level forms). For example, this 
doesn't hang:

  (lambda ()
    '#1=(1 2 3 . #1#))

Here's a more interesting example, which is how I stumbled upon 
this issue in the first place:

  (defun cycle-pure (list)
    (declare (pure t) (side-effect-free t))
    (let ((newlist (append list ())))
      (nconc newlist newlist)))

  (defun test2 ()
    (cycle-pure '(1 2 3)))

(The definition of `cycle-pure' is copied from the `-cycle' 
function from the dash.el package.)

If `cycle-pure' is not yet defined when compiling, the compiler 
doesn't hang.

However, if `cycle-pure' is defined (e.g. via M-x eval-defun), the 
compiler hangs. This is weird because, unlike `test1' above, 
`test2' doesn't contain a circular list itself; it only builds it 
at run-time.

In contrast, this example doesn't hang, regardless of whether 
`cycle' is defined or not (note the removed declarations):

  (defun cycle (list)
    (let ((newlist (append list ())))
      (nconc newlist newlist)))

  (defun test3 ()
    (cycle '(1 2 3)))

My conjecture is that the `pure' and `side-effect-free' 
declarations within `cycle-pure' (which I assume are picked up 
only once the function definition is loaded) allow the compiler to 
do some constant folding when it sees the expression `(cycle-pure 
'(1 2 3))'. This results in the compiler manipulating a circular 
list at compile-time, just like in `test1', and leads to a hang.

Kind regards,
hokomo