static struct Lisp_Vector *
next_vector (struct Lisp_Vector *v)
{
- return XUNTAG (v->contents[0], Lisp_Int0);
+ return XUNTAG (v->contents[0], Lisp_Int0, struct Lisp_Vector);
}
static void
XBUFFER (Lisp_Object a)
{
eassert (BUFFERP (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct buffer);
}
/* Most code should use these functions to set Lisp fields in struct
# define __has_attribute_no_sanitize_undefined GNUC_PREREQ (4, 9, 0)
#endif
-/* Simulate __has_builtin on compilers that lack it. It is used only
- on arguments like __builtin_assume_aligned that are handled in this
- simulation. */
-#ifndef __has_builtin
-# define __has_builtin(a) __has_builtin_##a
-# define __has_builtin___builtin_assume_aligned GNUC_PREREQ (4, 7, 0)
-#endif
-
/* Simulate __has_feature on compilers that lack it. It is used only
to define ADDRESS_SANITIZER below. */
#ifndef __has_feature
# define ADDRESS_SANITIZER false
#endif
-/* Yield PTR, which must be aligned to ALIGNMENT. */
-#if ! __has_builtin (__builtin_assume_aligned)
-# define __builtin_assume_aligned(ptr, ...) ((void *) (ptr))
-#endif
-
#ifdef DARWIN_OS
#if defined emacs && !defined CANNOT_DUMP
#define malloc unexec_malloc
: (STRINGP (object)) ? DBUS_TYPE_STRING \
: (XD_DBUS_TYPE_P (object)) ? xd_symbol_to_dbus_type (object) \
: (CONSP (object)) \
- ? ((XD_DBUS_TYPE_P (CAR_SAFE (object))) \
- ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (CAR_SAFE (object)))) \
+ ? ((XD_DBUS_TYPE_P (XCAR (object))) \
+ ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (XCAR (object)))) \
? DBUS_TYPE_ARRAY \
- : xd_symbol_to_dbus_type (CAR_SAFE (object))) \
+ : xd_symbol_to_dbus_type (XCAR (object))) \
: DBUS_TYPE_ARRAY) \
: DBUS_TYPE_INVALID)
CHECK_CONS (object);
/* Type symbol is optional. */
- if (EQ (QCarray, CAR_SAFE (elt)))
+ if (EQ (QCarray, XCAR (elt)))
elt = XD_NEXT_VALUE (elt);
/* If the array is empty, DBUS_TYPE_STRING is the default
/* If the element type is DBUS_TYPE_SIGNATURE, and this is the
only element, the value of this element is used as the
array's element signature. */
- if ((subtype == DBUS_TYPE_SIGNATURE)
- && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt)))
- && NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
- subsig = SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt)));
+ if (subtype == DBUS_TYPE_SIGNATURE)
+ {
+ Lisp_Object elt1 = XD_NEXT_VALUE (elt);
+ if (CONSP (elt1) && STRINGP (XCAR (elt1)) && NILP (XCDR (elt1)))
+ subsig = SSDATA (XCAR (elt1));
+ }
while (!NILP (elt))
{
#endif
}
- if (!NILP (default_directory))
+ handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
+ if (!NILP (handler))
{
- handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
- if (!NILP (handler))
- {
- handled_name = call3 (handler, Qexpand_file_name,
- name, default_directory);
- if (STRINGP (handled_name))
- return handled_name;
- error ("Invalid handler in `file-name-handler-alist'");
- }
+ handled_name = call3 (handler, Qexpand_file_name,
+ name, default_directory);
+ if (STRINGP (handled_name))
+ return handled_name;
+ error ("Invalid handler in `file-name-handler-alist'");
}
{
Lisp_Object val, tmp, cache = driver_list->driver->get_cache (f);
val = XCDR (cache);
- while (! NILP (val)
- && ! EQ (XCAR (XCAR (val)), driver_list->driver->type))
+ while (eassert (CONSP (val)),
+ ! EQ (XCAR (XCAR (val)), driver_list->driver->type))
val = XCDR (val);
- eassert (! NILP (val));
tmp = XCDR (XCAR (val));
if (XINT (XCAR (tmp)) == 0)
{
XFONT_SPEC (Lisp_Object p)
{
eassert (FONT_SPEC_P (p));
- return XUNTAG (p, Lisp_Vectorlike);
+ return XUNTAG (p, Lisp_Vectorlike, struct font_spec);
}
INLINE struct font_spec *
GC_XFONT_SPEC (Lisp_Object p)
{
eassert (GC_FONT_SPEC_P (p));
- return XUNTAG (p, Lisp_Vectorlike);
+ return XUNTAG (p, Lisp_Vectorlike, struct font_spec);
}
INLINE struct font_entity *
XFONT_ENTITY (Lisp_Object p)
{
eassert (FONT_ENTITY_P (p));
- return XUNTAG (p, Lisp_Vectorlike);
+ return XUNTAG (p, Lisp_Vectorlike, struct font_entity);
}
INLINE struct font_entity *
GC_XFONT_ENTITY (Lisp_Object p)
{
eassert (GC_FONT_ENTITY_P (p));
- return XUNTAG (p, Lisp_Vectorlike);
+ return XUNTAG (p, Lisp_Vectorlike, struct font_entity);
}
INLINE struct font *
XFONT_OBJECT (Lisp_Object p)
{
eassert (FONT_OBJECT_P (p));
- return XUNTAG (p, Lisp_Vectorlike);
+ return XUNTAG (p, Lisp_Vectorlike, struct font);
}
INLINE struct font *
GC_XFONT_OBJECT (Lisp_Object p)
{
eassert (GC_FONT_OBJECT_P (p));
- return XUNTAG (p, Lisp_Vectorlike);
+ return XUNTAG (p, Lisp_Vectorlike, struct font);
}
#define XSETFONT(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_FONT))
#define FRAME_IMAGE_CACHE(F) ((F)->terminal->image_cache)
#define XFRAME(p) \
- (eassert (FRAMEP (p)), (struct frame *) XUNTAG (p, Lisp_Vectorlike))
+ (eassert (FRAMEP (p)), XUNTAG (p, Lisp_Vectorlike, struct frame))
#define XSETFRAME(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_FRAME))
/* Given a window, return its frame as a Lisp_Object. */
static char *find_user_signal_name (int);
static void store_user_signal_events (void);
+/* Like EVENT_START, but assume EVENT is an event.
+ This pacifies gcc -Wnull-dereference, which might otherwise
+ complain about earlier checks that EVENT is indeed an event. */
+static Lisp_Object
+xevent_start (Lisp_Object event)
+{
+ return XCAR (XCDR (event));
+}
+
/* These setters are used only in this file, so they can be private. */
static void
kset_echo_string (struct kboard *kb, Lisp_Object val)
so we won't do this twice, then queue it up. */
if (EVENT_HAS_PARAMETERS (c)
&& CONSP (XCDR (c))
- && CONSP (EVENT_START (c))
- && CONSP (XCDR (EVENT_START (c))))
+ && CONSP (xevent_start (c))
+ && CONSP (XCDR (xevent_start (c))))
{
Lisp_Object posn;
}
}
else if (CONSP (XCDR (key))
- && CONSP (EVENT_START (key))
- && CONSP (XCDR (EVENT_START (key))))
+ && CONSP (xevent_start (key))
+ && CONSP (XCDR (xevent_start (key))))
{
Lisp_Object posn;
- posn = POSN_POSN (EVENT_START (key));
+ posn = POSN_POSN (xevent_start (key));
/* Handle menu-bar events:
insert the dummy prefix event `menu-bar'. */
if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
/* Zap the position in key, so we know that we've
expanded it, and don't try to do so again. */
- POSN_SET_POSN (EVENT_START (key), list1 (posn));
+ POSN_SET_POSN (xevent_start (key), list1 (posn));
mock_input = t + 2;
goto replay_sequence;
#define lisp_h_XCAR(c) XCONS (c)->u.s.car
#define lisp_h_XCDR(c) XCONS (c)->u.s.u.cdr
#define lisp_h_XCONS(a) \
- (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons))
+ (eassert (CONSP (a)), XUNTAG (a, Lisp_Cons, struct Lisp_Cons))
#define lisp_h_XHASH(a) XUINT (a)
#ifndef GC_CHECK_CONS_LIST
# define lisp_h_check_cons_list() ((void) 0)
# ifdef __CHKP__
# define lisp_h_XSYMBOL(a) \
(eassert (SYMBOLP (a)), \
- (struct Lisp_Symbol *) ((char *) XUNTAG (a, Lisp_Symbol) \
+ (struct Lisp_Symbol *) ((char *) XUNTAG (a, Lisp_Symbol, \
+ struct Lisp_Symbol) \
+ (intptr_t) lispsym))
# else
/* If !__CHKP__ this is equivalent, and is a bit faster as of GCC 7. */
+ (char *) lispsym))
# endif
# define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
-# define lisp_h_XUNTAG(a, type) \
- __builtin_assume_aligned ((char *) XLP (a) - (type), GCALIGNMENT)
#endif
/* When compiling via gcc -O0, define the key operations as macros, as
# define XINT(a) lisp_h_XINT (a)
# define XSYMBOL(a) lisp_h_XSYMBOL (a)
# define XTYPE(a) lisp_h_XTYPE (a)
-# define XUNTAG(a, type) lisp_h_XUNTAG (a, type)
# endif
#endif
lisp_h_CHECK_TYPE (ok, predicate, x);
}
-/* Extract A's pointer value, assuming A's type is TYPE. */
-
-INLINE void *
-(XUNTAG) (Lisp_Object a, int type)
-{
-#if USE_LSB_TAG
- return lisp_h_XUNTAG (a, type);
-#else
- EMACS_UINT utype = type;
- char *p = XLP (a);
- return p - (utype << (USE_LSB_TAG ? 0 : VALBITS));
-#endif
-}
+/* Extract A's pointer value, assuming A's Lisp type is TYPE and the
+ extracted pointer's type is CTYPE *. */
+#define XUNTAG(a, type, ctype) ((ctype *) \
+ ((char *) XLP (a) - LISP_WORD_TAG (type)))
\f
/* Interned state of a symbol. */
#define DEFUN_ARGS_8 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
-/* Typedefs useful for implementing TAG_PTR. untagged_ptr represents
- a pointer before tagging, and Lisp_Word_tag contains a
- possibly-shifted tag to be added to an untagged_ptr to convert it
- to a Lisp_Word. */
+/* untagged_ptr represents a pointer before tagging, and Lisp_Word_tag
+ contains a possibly-shifted tag to be added to an untagged_ptr to
+ convert it to a Lisp_Word. */
#if LISP_WORDS_ARE_POINTERS
/* untagged_ptr is a pointer so that the compiler knows that TAG_PTR
yields a pointer; this can help with gcc -fcheck-pointer-bounds.
typedef EMACS_UINT Lisp_Word_tag;
#endif
+/* A integer value tagged with TAG, and otherwise all zero. */
+#define LISP_WORD_TAG(tag) \
+ ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))
+
/* An initializer for a Lisp_Object that contains TAG along with PTR. */
#define TAG_PTR(tag, ptr) \
- LISP_INITIALLY ((Lisp_Word) \
- ((untagged_ptr) (ptr) \
- + ((Lisp_Word_tag) (tag) << (USE_LSB_TAG ? 0 : VALBITS))))
+ LISP_INITIALLY ((Lisp_Word) ((untagged_ptr) (ptr) + LISP_WORD_TAG (tag)))
/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
designed for use as an initializer, even for a constant initializer. */
return lisp_h_XSYMBOL (a);
#else
eassert (SYMBOLP (a));
- intptr_t i = (intptr_t) XUNTAG (a, Lisp_Symbol);
+ intptr_t i = (intptr_t) XUNTAG (a, Lisp_Symbol, struct Lisp_Symbol);
void *p = (char *) lispsym + i;
# ifdef __CHKP__
/* Bypass pointer checking. Although this could be improved it is
make_lisp_ptr (void *ptr, enum Lisp_Type type)
{
Lisp_Object a = TAG_PTR (type, ptr);
- eassert (XTYPE (a) == type && XUNTAG (a, type) == ptr);
+ eassert (XTYPE (a) == type && XUNTAG (a, type, char) == ptr);
return a;
}
/* The cast to union vectorlike_header * avoids aliasing issues. */
#define XSETPSEUDOVECTOR(a, b, code) \
XSETTYPED_PSEUDOVECTOR (a, b, \
- (((union vectorlike_header *) \
- XUNTAG (a, Lisp_Vectorlike)) \
+ (XUNTAG (a, Lisp_Vectorlike, \
+ union vectorlike_header) \
->size), \
code)
#define XSETTYPED_PSEUDOVECTOR(a, b, size, code) \
INLINE void *
XINTPTR (Lisp_Object a)
{
- return XUNTAG (a, Lisp_Int0);
+ return XUNTAG (a, Lisp_Int0, char);
}
INLINE Lisp_Object
XSTRING (Lisp_Object a)
{
eassert (STRINGP (a));
- return XUNTAG (a, Lisp_String);
+ return XUNTAG (a, Lisp_String, struct Lisp_String);
}
/* True if STR is a multibyte string. */
XVECTOR (Lisp_Object a)
{
eassert (VECTORLIKEP (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Vector);
}
INLINE ptrdiff_t
else
{
/* Converting to union vectorlike_header * avoids aliasing issues. */
- union vectorlike_header *h = XUNTAG (a, Lisp_Vectorlike);
- return PSEUDOVECTOR_TYPEP (h, code);
+ return PSEUDOVECTOR_TYPEP (XUNTAG (a, Lisp_Vectorlike,
+ union vectorlike_header),
+ code);
}
}
XBOOL_VECTOR (Lisp_Object a)
{
eassert (BOOL_VECTOR_P (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Bool_Vector);
}
INLINE EMACS_INT
XCHAR_TABLE (Lisp_Object a)
{
eassert (CHAR_TABLE_P (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Char_Table);
}
struct Lisp_Sub_Char_Table
XSUB_CHAR_TABLE (Lisp_Object a)
{
eassert (SUB_CHAR_TABLE_P (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Sub_Char_Table);
}
INLINE Lisp_Object
XSUBR (Lisp_Object a)
{
eassert (SUBRP (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Subr);
}
enum char_table_specials
XHASH_TABLE (Lisp_Object a)
{
eassert (HASH_TABLE_P (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Hash_Table);
}
#define XSET_HASH_TABLE(VAR, PTR) \
XMISCANY (Lisp_Object a)
{
eassert (MISCP (a));
- return XUNTAG (a, Lisp_Misc);
+ return XUNTAG (a, Lisp_Misc, struct Lisp_Misc_Any);
}
INLINE enum Lisp_Misc_Type
XSAVE_VALUE (Lisp_Object a)
{
eassert (SAVE_VALUEP (a));
- return XUNTAG (a, Lisp_Misc);
+ return XUNTAG (a, Lisp_Misc, struct Lisp_Save_Value);
}
/* Return the type of V's Nth saved value. */
XFINALIZER (Lisp_Object a)
{
eassert (FINALIZERP (a));
- return XUNTAG (a, Lisp_Misc);
+ return XUNTAG (a, Lisp_Misc, struct Lisp_Finalizer);
}
/* A miscellaneous object, when it's on the free list. */
INLINE union Lisp_Misc *
XMISC (Lisp_Object a)
{
- return XUNTAG (a, Lisp_Misc);
+ return XUNTAG (a, Lisp_Misc, union Lisp_Misc);
}
INLINE bool
XMARKER (Lisp_Object a)
{
eassert (MARKERP (a));
- return XUNTAG (a, Lisp_Misc);
+ return XUNTAG (a, Lisp_Misc, struct Lisp_Marker);
}
INLINE bool
XOVERLAY (Lisp_Object a)
{
eassert (OVERLAYP (a));
- return XUNTAG (a, Lisp_Misc);
+ return XUNTAG (a, Lisp_Misc, struct Lisp_Overlay);
}
#ifdef HAVE_MODULES
XUSER_PTR (Lisp_Object a)
{
eassert (USER_PTRP (a));
- return XUNTAG (a, Lisp_Misc);
+ return XUNTAG (a, Lisp_Misc, struct Lisp_User_Ptr);
}
#endif
XFLOAT (Lisp_Object a)
{
eassert (FLOATP (a));
- return XUNTAG (a, Lisp_Float);
+ return XUNTAG (a, Lisp_Float, struct Lisp_Float);
}
INLINE double
XMODULE_FUNCTION (Lisp_Object o)
{
eassert (MODULE_FUNCTIONP (o));
- return XUNTAG (o, Lisp_Vectorlike);
+ return XUNTAG (o, Lisp_Vectorlike, struct Lisp_Module_Function);
}
#ifdef HAVE_MODULES
else
{
menuflags |= MENU_FOR_CLICK;
- tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
+ tem = Fcar (XCDR (position)); /* EVENT_START (position) */
window = Fcar (tem); /* POSN_WINDOW (tem) */
tem2 = Fcar (Fcdr (tem)); /* POSN_POSN (tem) */
/* The MENU_KBD_NAVIGATION field is set when the menu
event. */
if (!EQ (POSN_POSN (last_nonmenu_event),
POSN_POSN (position))
- && CONSP (tem2) && EQ (Fcar (tem2), Qmenu_bar))
+ && CONSP (tem2) && EQ (XCAR (tem2), Qmenu_bar))
menuflags |= MENU_KBD_NAVIGATION;
tem = Fcar (Fcdr (Fcdr (tem))); /* POSN_WINDOW_POSN (tem) */
x = Fcar (tem);
XPROCESS (Lisp_Object a)
{
eassert (PROCESSP (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Process);
}
/* Every field in the preceding structure except for the first two
XTERMINAL (Lisp_Object a)
{
eassert (TERMINALP (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct terminal);
}
/* Most code should use these functions to set Lisp fields in struct
XTHREAD (Lisp_Object a)
{
eassert (THREADP (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct thread_state);
}
/* A mutex in lisp is represented by a system condition variable.
XMUTEX (Lisp_Object a)
{
eassert (MUTEXP (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Mutex);
}
/* A condition variable as a lisp object. */
XCONDVAR (Lisp_Object a)
{
eassert (CONDVARP (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct Lisp_CondVar);
}
extern struct thread_state *current_thread;
eassert (CONSP (item));
/* Pass the tail of the list as a pointer to a Lisp_Cons cell,
so that it works in a --with-wide-int build as well. */
- lparam = (LPARAM) XUNTAG (item, Lisp_Cons);
+ lparam = (LPARAM) XUNTAG (item, Lisp_Cons, struct Lisp_Cons);
/* Notify input thread about hot-key definition being removed, so
that it takes effect without needing focus switch. */
Windows alike. MSVC headers get it right; hopefully,
MinGW headers will, too. */
eassert (STRINGP (wv->help));
- info.dwItemData = (ULONG_PTR) XUNTAG (wv->help, Lisp_String);
+ info.dwItemData = (ULONG_PTR) XUNTAG (wv->help, Lisp_String,
+ struct Lisp_String);
}
if (wv->button_type == BUTTON_TYPE_RADIO)
{
XWINDOW (Lisp_Object a)
{
eassert (WINDOWP (a));
- return XUNTAG (a, Lisp_Vectorlike);
+ return XUNTAG (a, Lisp_Vectorlike, struct window);
}
/* Most code should use these functions to set Lisp fields in struct
/* Test for xwidget pseudovector. */
#define XWIDGETP(x) PSEUDOVECTORP (x, PVEC_XWIDGET)
#define XXWIDGET(a) (eassert (XWIDGETP (a)), \
- (struct xwidget *) XUNTAG (a, Lisp_Vectorlike))
+ XUNTAG (a, Lisp_Vectorlike, struct xwidget))
#define CHECK_XWIDGET(x) \
CHECK_TYPE (XWIDGETP (x), Qxwidgetp, x)
/* Test for xwidget_view pseudovector. */
#define XWIDGET_VIEW_P(x) PSEUDOVECTORP (x, PVEC_XWIDGET_VIEW)
#define XXWIDGET_VIEW(a) (eassert (XWIDGET_VIEW_P (a)), \
- (struct xwidget_view *) XUNTAG (a, Lisp_Vectorlike))
+ XUNTAG (a, Lisp_Vectorlike, struct xwidget_view))
#define CHECK_XWIDGET_VIEW(x) \
CHECK_TYPE (XWIDGET_VIEW_P (x), Qxwidget_view_p, x)