Port flexible array members to GCC + valgrind
These changes are needed to conform to the C standard's rule for allocating structs containing flexible array members. C11 says that malloc (offsetof (struct s, m) + n) does not suffice to allocate a struct with an n-byte tail; instead, malloc’s arg should be rounded up to the nearest multiple of alignof (struct s). Although this is arguably a defect in C11, gcc -O2 + valgrind sometimes complains when this rule is violated, and when debugging it’s better to keep valgrind happy. For details please see the thread containing the message at: https://gcc.gnu.org/ml/gcc-patches/2016-09/msg00416.html * lib-src/ebrowse.c, src/alloc.c, src/image.c, src/process.c: Include flexmember.h. * lib-src/ebrowse.c (add_sym, add_member, make_namespace) (register_namespace_alias): * src/alloc.c (SDATA_SIZE, allocate_string_data): * src/image.c (xpm_cache_color, imagemagick_create_cache): * src/process.c (Fmake_network_process): Use FLEXSIZEOF instead of offsetof and addition. * src/alloc.c (SDATA_SIZE, vector_alignment): Use FLEXALIGNOF instead of sizeof (ptrdiff_t). * src/lisp.h (ALIGNOF_STRUCT_LISP_VECTOR): Remove, as alloc.c can now calculate this on its own.
This commit is contained in:
parent
12a7e0f88e
commit
d2f1971dd5
5 changed files with 26 additions and 32 deletions
|
@ -32,6 +32,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#define SEEK_END 2
|
||||
#endif
|
||||
|
||||
#include <flexmember.h>
|
||||
#include <min-max.h>
|
||||
|
||||
/* Files are read in chunks of this number of bytes. */
|
||||
|
@ -582,7 +583,7 @@ add_sym (const char *name, struct sym *nested_in_class)
|
|||
puts (name);
|
||||
}
|
||||
|
||||
sym = xmalloc (offsetof (struct sym, name) + strlen (name) + 1);
|
||||
sym = xmalloc (FLEXSIZEOF (struct sym, name, strlen (name) + 1));
|
||||
memset (sym, 0, offsetof (struct sym, name));
|
||||
strcpy (sym->name, name);
|
||||
sym->namesp = scope;
|
||||
|
@ -867,8 +868,8 @@ add_global_decl (char *name, char *regexp, int pos, unsigned int hash, int var,
|
|||
static struct member *
|
||||
add_member (struct sym *cls, char *name, int var, int sc, unsigned int hash)
|
||||
{
|
||||
struct member *m = xmalloc (offsetof (struct member, name)
|
||||
+ strlen (name) + 1);
|
||||
struct member *m = xmalloc (FLEXSIZEOF (struct member, name,
|
||||
strlen (name) + 1));
|
||||
struct member **list;
|
||||
struct member *p;
|
||||
struct member *prev;
|
||||
|
@ -978,7 +979,7 @@ mark_inherited_virtual (void)
|
|||
static struct sym *
|
||||
make_namespace (char *name, struct sym *context)
|
||||
{
|
||||
struct sym *s = xmalloc (offsetof (struct sym, name) + strlen (name) + 1);
|
||||
struct sym *s = xmalloc (FLEXSIZEOF (struct sym, name, strlen (name) + 1));
|
||||
memset (s, 0, offsetof (struct sym, name));
|
||||
strcpy (s->name, name);
|
||||
s->next = all_namespaces;
|
||||
|
@ -1062,7 +1063,7 @@ register_namespace_alias (char *new_name, struct link *old_name)
|
|||
if (streq (new_name, al->name) && (al->namesp == current_namespace))
|
||||
return;
|
||||
|
||||
al = xmalloc (offsetof (struct alias, name) + strlen (new_name) + 1);
|
||||
al = xmalloc (FLEXSIZEOF (struct alias, name, strlen (new_name) + 1));
|
||||
strcpy (al->name, new_name);
|
||||
al->next = namespace_alias_table[h];
|
||||
al->namesp = current_namespace;
|
||||
|
|
27
src/alloc.c
27
src/alloc.c
|
@ -46,6 +46,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include TERM_HEADER
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
||||
#include <flexmember.h>
|
||||
#include <verify.h>
|
||||
#include <execinfo.h> /* For backtrace. */
|
||||
|
||||
|
@ -1757,27 +1758,23 @@ static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] =
|
|||
|
||||
#ifdef GC_CHECK_STRING_BYTES
|
||||
|
||||
#define SDATA_SIZE(NBYTES) \
|
||||
((SDATA_DATA_OFFSET \
|
||||
+ (NBYTES) + 1 \
|
||||
+ sizeof (ptrdiff_t) - 1) \
|
||||
& ~(sizeof (ptrdiff_t) - 1))
|
||||
#define SDATA_SIZE(NBYTES) FLEXSIZEOF (struct sdata, data, NBYTES)
|
||||
|
||||
#else /* not GC_CHECK_STRING_BYTES */
|
||||
|
||||
/* The 'max' reserves space for the nbytes union member even when NBYTES + 1 is
|
||||
less than the size of that member. The 'max' is not needed when
|
||||
SDATA_DATA_OFFSET is a multiple of sizeof (ptrdiff_t), because then the
|
||||
alignment code reserves enough space. */
|
||||
SDATA_DATA_OFFSET is a multiple of FLEXALIGNOF (struct sdata),
|
||||
because then the alignment code reserves enough space. */
|
||||
|
||||
#define SDATA_SIZE(NBYTES) \
|
||||
((SDATA_DATA_OFFSET \
|
||||
+ (SDATA_DATA_OFFSET % sizeof (ptrdiff_t) == 0 \
|
||||
+ (SDATA_DATA_OFFSET % FLEXALIGNOF (struct sdata) == 0 \
|
||||
? NBYTES \
|
||||
: max (NBYTES, sizeof (ptrdiff_t) - 1)) \
|
||||
: max (NBYTES, FLEXALIGNOF (struct sdata) - 1)) \
|
||||
+ 1 \
|
||||
+ sizeof (ptrdiff_t) - 1) \
|
||||
& ~(sizeof (ptrdiff_t) - 1))
|
||||
+ FLEXALIGNOF (struct sdata) - 1) \
|
||||
& ~(FLEXALIGNOF (struct sdata) - 1))
|
||||
|
||||
#endif /* not GC_CHECK_STRING_BYTES */
|
||||
|
||||
|
@ -1997,7 +1994,7 @@ allocate_string_data (struct Lisp_String *s,
|
|||
|
||||
if (nbytes > LARGE_STRING_BYTES)
|
||||
{
|
||||
size_t size = offsetof (struct sblock, data) + needed;
|
||||
size_t size = FLEXSIZEOF (struct sblock, data, needed);
|
||||
|
||||
#ifdef DOUG_LEA_MALLOC
|
||||
if (!mmap_lisp_allowed_p ())
|
||||
|
@ -2953,15 +2950,15 @@ set_next_vector (struct Lisp_Vector *v, struct Lisp_Vector *p)
|
|||
enum
|
||||
{
|
||||
/* Alignment of struct Lisp_Vector objects. */
|
||||
vector_alignment = COMMON_MULTIPLE (ALIGNOF_STRUCT_LISP_VECTOR,
|
||||
GCALIGNMENT),
|
||||
vector_alignment = COMMON_MULTIPLE (FLEXALIGNOF (struct Lisp_Vector),
|
||||
GCALIGNMENT),
|
||||
|
||||
/* Vector size requests are a multiple of this. */
|
||||
roundup_size = COMMON_MULTIPLE (vector_alignment, word_size)
|
||||
};
|
||||
|
||||
/* Verify assumptions described above. */
|
||||
verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0);
|
||||
verify (VECTOR_BLOCK_SIZE % roundup_size == 0);
|
||||
verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
|
||||
|
||||
/* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at compile time. */
|
||||
|
|
|
@ -30,7 +30,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#endif
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <c-ctype.h>
|
||||
#include <flexmember.h>
|
||||
|
||||
#include "lisp.h"
|
||||
#include "frame.h"
|
||||
|
@ -3347,7 +3349,7 @@ xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket)
|
|||
if (bucket < 0)
|
||||
bucket = xpm_color_bucket (color_name);
|
||||
|
||||
nbytes = offsetof (struct xpm_cached_color, name) + strlen (color_name) + 1;
|
||||
nbytes = FLEXSIZEOF (struct xpm_cached_color, name, strlen (color_name) + 1);
|
||||
p = xmalloc (nbytes);
|
||||
strcpy (p->name, color_name);
|
||||
p->color = *color;
|
||||
|
@ -8328,8 +8330,8 @@ static struct animation_cache *
|
|||
imagemagick_create_cache (char *signature)
|
||||
{
|
||||
struct animation_cache *cache
|
||||
= xmalloc (offsetof (struct animation_cache, signature)
|
||||
+ strlen (signature) + 1);
|
||||
= xmalloc (FLEXSIZEOF (struct animation_cache, signature,
|
||||
strlen (signature) + 1));
|
||||
cache->wand = 0;
|
||||
cache->index = 0;
|
||||
cache->next = 0;
|
||||
|
|
|
@ -1429,13 +1429,6 @@ struct Lisp_Vector
|
|||
Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER];
|
||||
};
|
||||
|
||||
/* C11 prohibits alignof (struct Lisp_Vector), so compute it manually. */
|
||||
enum
|
||||
{
|
||||
ALIGNOF_STRUCT_LISP_VECTOR
|
||||
= alignof (union { struct vectorlike_header a; Lisp_Object b; })
|
||||
};
|
||||
|
||||
/* A boolvector is a kind of vectorlike, with contents like a string. */
|
||||
|
||||
struct Lisp_Bool_Vector
|
||||
|
|
|
@ -88,6 +88,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#endif
|
||||
|
||||
#include <c-ctype.h>
|
||||
#include <flexmember.h>
|
||||
#include <sig2str.h>
|
||||
#include <verify.h>
|
||||
|
||||
|
@ -3807,8 +3808,8 @@ usage: (make-network-process &rest ARGS) */)
|
|||
struct gaicb gaicb;
|
||||
struct addrinfo hints;
|
||||
char str[FLEXIBLE_ARRAY_MEMBER];
|
||||
} *req = xmalloc (offsetof (struct req, str)
|
||||
+ hostlen + 1 + portstringlen + 1);
|
||||
} *req = xmalloc (FLEXSIZEOF (struct req, str,
|
||||
hostlen + 1 + portstringlen + 1));
|
||||
dns_request = &req->gaicb;
|
||||
dns_request->ar_name = req->str;
|
||||
dns_request->ar_service = req->str + hostlen + 1;
|
||||
|
|
Loading…
Add table
Reference in a new issue