Subject: Re: bug#75581: 30.0.93; Crash when copy-sequence on clear-string'ed multibyte strings with text properties

From: Pip Cet <[email-masked]>
Date: Thu, 16 Jan 2025 11:17:05 +0000

"Eli Zaretskii" <[email-masked]> writes:

>> Cc: [email-masked], Kanakana <[email-masked]>,
>>  Andreas Schwab <[email-masked]>
>> Date: Thu, 16 Jan 2025 00:03:10 +0000
>> From:  Pip Cet via "Bug reports for GNU Emacs,
>>  the Swiss army knife of text editors" <[email-masked]>
>>
>> > No need, I had forgotten the strange way STRING_SET_MULTIBYTE treats its
>> > argument as an lvalue.  It's a minor issue, but I would prefer it if the
>> > argument were provided as a pointer to a Lisp_Object so it's clear it
>> > can be modified.
>>
>> Patch (I've verified that the eassume-in-a-loop thing doesn't generate
>> any code with current GCC, but it'd be nice to check this for clang):
>
> We have many SET_SOMETHING macros that modify the objects passed to
> them as arguments.

The problem is treating the arguments as lvalues and turning them into
entirely different objects.  XSET* does that, and there are a few macros
that set structs, but I'm aware of only two macros that do this to Lisp
objects, and the other one is clearly named to indicate it coerces its
argument.

So, no, not many cases like this, and this case is bad for other
reasons: assuming that STRING_SET_MULTIBYTE and STRING_SET_UNIBYTE
behave similarly seems natural to me.

> So I see no compelling reason to make this change,
> which confusingly deviates from the other SET macros.

??? Which other *_SET_* macro assumes it is passed an lval, and turns it
into an object with a different identity?  Note that "STRING_SET_"
doesn't start with "SET" or "XSET", and that distinction is important.

> Let's leave alone this code, which worked for us for many years.

I have no problem with reaching that decision ultimately, but the
premises you used to reach it aren't correct: there are no comparable
macros that do this, AFAIK.

>> (I'd also like to propose that (aset str 0 x) always should work on
>> single-character strings; right now, if str contains a single unibyte
>> non-ASCII string and x is >= 0x100, the aset will fail, which seems
>> weird to me).

Sorry, I meant to say "non-ASCII character".

> This is a separate issue with (AFAIR) a long history.  It should be
> discussed separately.  And I don't think I understand the situation
> you describe; the below recipe doesn't signal an error (or did you
> mean a different kind of failure?):
>
>   (setq str "a")
>   (multibyte-string-p str)
>     => nil
>   (aset str 0 #x100)
>     => 256
>   str
>     => "Ā"
>   (multibyte-string-p str)
>     => t

The situation I described was:

(setq str "a")
(aset str 0 #xff)
(aset str 0 #x100)

Pip