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

From: Eli Zaretskii <[email-masked]>
Date: Thu, 16 Jan 2025 13:52:03 +0200

> Date: Thu, 16 Jan 2025 11:17:05 +0000
> From: Pip Cet <[email-masked]>
> Cc: [email-masked], [email-masked], [email-masked], [email-masked]
> 
> "Eli Zaretskii" <[email-masked]> writes:
> 
> > 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.

I said nothing about lvalues and identities.  I was talking about the
various SET* macros: the XSET* ones, SSET, STRING_SET_CHARS, ASET, and
CHAR_TABLE_SET, to name just a few.  They all create or modify Lisp
objects, and they all accept the objects directly, not as a pointer.

> > 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.

There are for me: I'm used to these macros from 30 years of hacking
Emacs, and they all receive Lisp objects, not pointers to them.  So
having one or two macros that break this pattern will be confusing,
certainly after so many years of using the same macros as we do now.

> The situation I described was:
> 
> (setq str "a")
> (aset str 0 #xff)
> (aset str 0 #x100)

OK, but why is this weird?  The value #x100 cannot be represented by a
single byte, so we refuse.  Looks understandable to me.