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 17:11:01 +0200

> Date: Thu, 16 Jan 2025 14:54:55 +0000
> From: Pip Cet <[email-masked]>
> Cc: [email-masked], [email-masked], [email-masked], [email-masked]
> 
> I'm not sure about the XSET* macros, FWIW.  They're not type safe
> (fixable, to the extent XSETVECTOR can be type-safe):
> 
> +#define XSETCONS(a, b) ({ struct Lisp_Cons *c = (b); ((a) = make_lisp_ptr (c, Lisp_Cons)); })
> +#define XSETVECTOR(a, b) ({ union vectorlike_header *d = &(b)->header; struct Lisp_Vector *c = (struct Lisp_Vector *)(d); ((a) = make_lisp_ptr (c, Lisp_Vectorlike)); })
> 
> That doesn't reveal any bugs, but I don't really see the reason for
> their existence at this point.  I suspect the reason was originally to
> avoid struct assignment / struct return values, but that's no longer an
> issue.  (Another reason may have been avoiding intermediate Lisp_Object
> values because they couldn't be GCPRO'd).
> 
> If I have a struct Lisp_Cons *, and I want a Lisp_Object, it would feel
> natural to me to write
> 
> Lisp_Object x = make_lisp_cons (c);
> 
> No void *, no lvalue macro arguments, just an ordinary C expression.

I don't know why these macros were invented, that was long before my
time.  I won't be surprised to hear that they come from some ancient
prototype of Emacs or somesuch.  Perhaps Richard knows.

If we were developing Emacs from scratch today, we would probably use
something simpler.  But we've had those macros for so long, and for
each kind of Lisp object in Emacs, that removing them now would need
to have a very good reason.