2011-06-08 Paul Eggert <eggert@cs.ucla.edu>
+ * lisp.h (SAFE_ALLOCA_LISP): Check for integer overflow.
+ (struct Lisp_Save_Value): Use ptrdiff_t, not int, for 'integer' member.
+ * alloc.c (make_save_value): Integer argument is now of type
+ ptrdiff_t, not int.
+ (mark_object): Use ptrdiff_t, not int.
+ * lisp.h (pD): New macro.
+ * print.c (print_object): Use it.
+
* alloc.c: Use EMACS_INT, not int, to count objects.
(total_conses, total_markers, total_symbols, total_vector_size)
(total_free_conses, total_free_markers, total_free_symbols)
The unwind function can get the C values back using XSAVE_VALUE. */
Lisp_Object
-make_save_value (void *pointer, int integer)
+make_save_value (void *pointer, ptrdiff_t integer)
{
register Lisp_Object val;
register struct Lisp_Save_Value *p;
if (ptr->dogc)
{
Lisp_Object *p = (Lisp_Object *) ptr->pointer;
- int nelt;
+ ptrdiff_t nelt;
for (nelt = ptr->integer; nelt > 0; nelt--, p++)
mark_maybe_object (*p);
}
# define EMACS_UINT unsigned EMACS_INT
#endif
+/* Use pD to format ptrdiff_t values, which suffice for indexes into
+ buffers and strings. Emacs never allocates objects larger than
+ PTRDIFF_MAX bytes, as they cause problems with pointer subtraction.
+ In C99, pD can always be "t"; configure it here for the sake of
+ pre-C99 libraries such as glibc 2.0 and Solaris 8. */
+#if PTRDIFF_MAX == INT_MAX
+# define pD ""
+#elif PTRDIFF_MAX == LONG_MAX
+# define pD "l"
+#elif PTRDIFF_MAX == LLONG_MAX
+# define pD "ll"
+#else
+# define pD "t"
+#endif
+
/* Extra internal type checking? */
#ifdef ENABLE_CHECKING
area containing INTEGER potential Lisp_Objects. */
unsigned int dogc : 1;
void *pointer;
- int integer;
+ ptrdiff_t integer;
};
extern Lisp_Object make_float (double);
extern void display_malloc_warning (void);
extern int inhibit_garbage_collection (void);
-extern Lisp_Object make_save_value (void *, int);
+extern Lisp_Object make_save_value (void *, ptrdiff_t);
extern void free_marker (Lisp_Object);
extern void free_cons (struct Lisp_Cons *);
extern void init_alloc_once (void);
#define SAFE_ALLOCA_LISP(buf, nelt) \
do { \
- int size_ = (nelt) * sizeof (Lisp_Object); \
- if (size_ < MAX_ALLOCA) \
- buf = (Lisp_Object *) alloca (size_); \
- else \
+ if ((nelt) < MAX_ALLOCA / sizeof (Lisp_Object)) \
+ buf = (Lisp_Object *) alloca ((nelt) * sizeof (Lisp_Object)); \
+ else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Lisp_Object)) \
{ \
Lisp_Object arg_; \
- buf = (Lisp_Object *) xmalloc (size_); \
+ buf = (Lisp_Object *) xmalloc ((nelt) * sizeof (Lisp_Object)); \
arg_ = make_save_value (buf, nelt); \
XSAVE_VALUE (arg_)->dogc = 1; \
sa_must_free = 1; \
record_unwind_protect (safe_alloca_unwind, arg_); \
} \
+ else \
+ memory_full (SIZE_MAX); \
} while (0)
case Lisp_Misc_Save_Value:
strout ("#<save_value ", -1, -1, printcharfun);
- sprintf(buf, "ptr=%p int=%d",
+ sprintf(buf, "ptr=%p int=%"pD,
XSAVE_VALUE (obj)->pointer,
XSAVE_VALUE (obj)->integer);
strout (buf, -1, -1, printcharfun);