From: Paul Eggert Date: Thu, 8 Sep 2016 01:08:45 +0000 (-0700) Subject: Port flexible array members to GCC + valgrind X-Git-Tag: emacs-26.0.90~1636 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=d2f1971dd570439da4198fa76603b53b072060f8;p=emacs.git 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. --- diff --git a/lib-src/ebrowse.c b/lib-src/ebrowse.c index c59181f9464..7a262005df9 100644 --- a/lib-src/ebrowse.c +++ b/lib-src/ebrowse.c @@ -32,6 +32,7 @@ along with GNU Emacs. If not, see . */ #define SEEK_END 2 #endif +#include #include /* 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; diff --git a/src/alloc.c b/src/alloc.c index 67187f12ea6..5bbd5e55c42 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -46,6 +46,7 @@ along with GNU Emacs. If not, see . */ #include TERM_HEADER #endif /* HAVE_WINDOW_SYSTEM */ +#include #include #include /* 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. */ diff --git a/src/image.c b/src/image.c index 7a554ef1b63..f15c2788967 100644 --- a/src/image.c +++ b/src/image.c @@ -30,7 +30,9 @@ along with GNU Emacs. If not, see . */ #endif #include + #include +#include #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; diff --git a/src/lisp.h b/src/lisp.h index 97c8d9fe84f..29ed9fe8a2d 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -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 diff --git a/src/process.c b/src/process.c index 989511967ce..29bf43e0f29 100644 --- a/src/process.c +++ b/src/process.c @@ -88,6 +88,7 @@ along with GNU Emacs. If not, see . */ #endif #include +#include #include #include @@ -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;