diff options
| author | Paul Eggert | 2016-09-07 18:08:45 -0700 |
|---|---|---|
| committer | Paul Eggert | 2016-09-07 18:10:11 -0700 |
| commit | d2f1971dd570439da4198fa76603b53b072060f8 (patch) | |
| tree | 38b1ddbeda27b6ed6ac52205169624608cc597fd | |
| parent | 12a7e0f88eaa68aabe7e32589e2d5c8f776f6346 (diff) | |
| download | emacs-d2f1971dd570439da4198fa76603b53b072060f8.tar.gz emacs-d2f1971dd570439da4198fa76603b53b072060f8.zip | |
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.
| -rw-r--r-- | lib-src/ebrowse.c | 11 | ||||
| -rw-r--r-- | src/alloc.c | 27 | ||||
| -rw-r--r-- | src/image.c | 8 | ||||
| -rw-r--r-- | src/lisp.h | 7 | ||||
| -rw-r--r-- | src/process.c | 5 |
5 files changed, 26 insertions, 32 deletions
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 <http://www.gnu.org/licenses/>. */ | |||
| 32 | #define SEEK_END 2 | 32 | #define SEEK_END 2 |
| 33 | #endif | 33 | #endif |
| 34 | 34 | ||
| 35 | #include <flexmember.h> | ||
| 35 | #include <min-max.h> | 36 | #include <min-max.h> |
| 36 | 37 | ||
| 37 | /* Files are read in chunks of this number of bytes. */ | 38 | /* Files are read in chunks of this number of bytes. */ |
| @@ -582,7 +583,7 @@ add_sym (const char *name, struct sym *nested_in_class) | |||
| 582 | puts (name); | 583 | puts (name); |
| 583 | } | 584 | } |
| 584 | 585 | ||
| 585 | sym = xmalloc (offsetof (struct sym, name) + strlen (name) + 1); | 586 | sym = xmalloc (FLEXSIZEOF (struct sym, name, strlen (name) + 1)); |
| 586 | memset (sym, 0, offsetof (struct sym, name)); | 587 | memset (sym, 0, offsetof (struct sym, name)); |
| 587 | strcpy (sym->name, name); | 588 | strcpy (sym->name, name); |
| 588 | sym->namesp = scope; | 589 | sym->namesp = scope; |
| @@ -867,8 +868,8 @@ add_global_decl (char *name, char *regexp, int pos, unsigned int hash, int var, | |||
| 867 | static struct member * | 868 | static struct member * |
| 868 | add_member (struct sym *cls, char *name, int var, int sc, unsigned int hash) | 869 | add_member (struct sym *cls, char *name, int var, int sc, unsigned int hash) |
| 869 | { | 870 | { |
| 870 | struct member *m = xmalloc (offsetof (struct member, name) | 871 | struct member *m = xmalloc (FLEXSIZEOF (struct member, name, |
| 871 | + strlen (name) + 1); | 872 | strlen (name) + 1)); |
| 872 | struct member **list; | 873 | struct member **list; |
| 873 | struct member *p; | 874 | struct member *p; |
| 874 | struct member *prev; | 875 | struct member *prev; |
| @@ -978,7 +979,7 @@ mark_inherited_virtual (void) | |||
| 978 | static struct sym * | 979 | static struct sym * |
| 979 | make_namespace (char *name, struct sym *context) | 980 | make_namespace (char *name, struct sym *context) |
| 980 | { | 981 | { |
| 981 | struct sym *s = xmalloc (offsetof (struct sym, name) + strlen (name) + 1); | 982 | struct sym *s = xmalloc (FLEXSIZEOF (struct sym, name, strlen (name) + 1)); |
| 982 | memset (s, 0, offsetof (struct sym, name)); | 983 | memset (s, 0, offsetof (struct sym, name)); |
| 983 | strcpy (s->name, name); | 984 | strcpy (s->name, name); |
| 984 | s->next = all_namespaces; | 985 | s->next = all_namespaces; |
| @@ -1062,7 +1063,7 @@ register_namespace_alias (char *new_name, struct link *old_name) | |||
| 1062 | if (streq (new_name, al->name) && (al->namesp == current_namespace)) | 1063 | if (streq (new_name, al->name) && (al->namesp == current_namespace)) |
| 1063 | return; | 1064 | return; |
| 1064 | 1065 | ||
| 1065 | al = xmalloc (offsetof (struct alias, name) + strlen (new_name) + 1); | 1066 | al = xmalloc (FLEXSIZEOF (struct alias, name, strlen (new_name) + 1)); |
| 1066 | strcpy (al->name, new_name); | 1067 | strcpy (al->name, new_name); |
| 1067 | al->next = namespace_alias_table[h]; | 1068 | al->next = namespace_alias_table[h]; |
| 1068 | al->namesp = current_namespace; | 1069 | 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 <http://www.gnu.org/licenses/>. */ | |||
| 46 | #include TERM_HEADER | 46 | #include TERM_HEADER |
| 47 | #endif /* HAVE_WINDOW_SYSTEM */ | 47 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 48 | 48 | ||
| 49 | #include <flexmember.h> | ||
| 49 | #include <verify.h> | 50 | #include <verify.h> |
| 50 | #include <execinfo.h> /* For backtrace. */ | 51 | #include <execinfo.h> /* For backtrace. */ |
| 51 | 52 | ||
| @@ -1757,27 +1758,23 @@ static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] = | |||
| 1757 | 1758 | ||
| 1758 | #ifdef GC_CHECK_STRING_BYTES | 1759 | #ifdef GC_CHECK_STRING_BYTES |
| 1759 | 1760 | ||
| 1760 | #define SDATA_SIZE(NBYTES) \ | 1761 | #define SDATA_SIZE(NBYTES) FLEXSIZEOF (struct sdata, data, NBYTES) |
| 1761 | ((SDATA_DATA_OFFSET \ | ||
| 1762 | + (NBYTES) + 1 \ | ||
| 1763 | + sizeof (ptrdiff_t) - 1) \ | ||
| 1764 | & ~(sizeof (ptrdiff_t) - 1)) | ||
| 1765 | 1762 | ||
| 1766 | #else /* not GC_CHECK_STRING_BYTES */ | 1763 | #else /* not GC_CHECK_STRING_BYTES */ |
| 1767 | 1764 | ||
| 1768 | /* The 'max' reserves space for the nbytes union member even when NBYTES + 1 is | 1765 | /* The 'max' reserves space for the nbytes union member even when NBYTES + 1 is |
| 1769 | less than the size of that member. The 'max' is not needed when | 1766 | less than the size of that member. The 'max' is not needed when |
| 1770 | SDATA_DATA_OFFSET is a multiple of sizeof (ptrdiff_t), because then the | 1767 | SDATA_DATA_OFFSET is a multiple of FLEXALIGNOF (struct sdata), |
| 1771 | alignment code reserves enough space. */ | 1768 | because then the alignment code reserves enough space. */ |
| 1772 | 1769 | ||
| 1773 | #define SDATA_SIZE(NBYTES) \ | 1770 | #define SDATA_SIZE(NBYTES) \ |
| 1774 | ((SDATA_DATA_OFFSET \ | 1771 | ((SDATA_DATA_OFFSET \ |
| 1775 | + (SDATA_DATA_OFFSET % sizeof (ptrdiff_t) == 0 \ | 1772 | + (SDATA_DATA_OFFSET % FLEXALIGNOF (struct sdata) == 0 \ |
| 1776 | ? NBYTES \ | 1773 | ? NBYTES \ |
| 1777 | : max (NBYTES, sizeof (ptrdiff_t) - 1)) \ | 1774 | : max (NBYTES, FLEXALIGNOF (struct sdata) - 1)) \ |
| 1778 | + 1 \ | 1775 | + 1 \ |
| 1779 | + sizeof (ptrdiff_t) - 1) \ | 1776 | + FLEXALIGNOF (struct sdata) - 1) \ |
| 1780 | & ~(sizeof (ptrdiff_t) - 1)) | 1777 | & ~(FLEXALIGNOF (struct sdata) - 1)) |
| 1781 | 1778 | ||
| 1782 | #endif /* not GC_CHECK_STRING_BYTES */ | 1779 | #endif /* not GC_CHECK_STRING_BYTES */ |
| 1783 | 1780 | ||
| @@ -1997,7 +1994,7 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1997 | 1994 | ||
| 1998 | if (nbytes > LARGE_STRING_BYTES) | 1995 | if (nbytes > LARGE_STRING_BYTES) |
| 1999 | { | 1996 | { |
| 2000 | size_t size = offsetof (struct sblock, data) + needed; | 1997 | size_t size = FLEXSIZEOF (struct sblock, data, needed); |
| 2001 | 1998 | ||
| 2002 | #ifdef DOUG_LEA_MALLOC | 1999 | #ifdef DOUG_LEA_MALLOC |
| 2003 | if (!mmap_lisp_allowed_p ()) | 2000 | if (!mmap_lisp_allowed_p ()) |
| @@ -2953,15 +2950,15 @@ set_next_vector (struct Lisp_Vector *v, struct Lisp_Vector *p) | |||
| 2953 | enum | 2950 | enum |
| 2954 | { | 2951 | { |
| 2955 | /* Alignment of struct Lisp_Vector objects. */ | 2952 | /* Alignment of struct Lisp_Vector objects. */ |
| 2956 | vector_alignment = COMMON_MULTIPLE (ALIGNOF_STRUCT_LISP_VECTOR, | 2953 | vector_alignment = COMMON_MULTIPLE (FLEXALIGNOF (struct Lisp_Vector), |
| 2957 | GCALIGNMENT), | 2954 | GCALIGNMENT), |
| 2958 | 2955 | ||
| 2959 | /* Vector size requests are a multiple of this. */ | 2956 | /* Vector size requests are a multiple of this. */ |
| 2960 | roundup_size = COMMON_MULTIPLE (vector_alignment, word_size) | 2957 | roundup_size = COMMON_MULTIPLE (vector_alignment, word_size) |
| 2961 | }; | 2958 | }; |
| 2962 | 2959 | ||
| 2963 | /* Verify assumptions described above. */ | 2960 | /* Verify assumptions described above. */ |
| 2964 | verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0); | 2961 | verify (VECTOR_BLOCK_SIZE % roundup_size == 0); |
| 2965 | verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS)); | 2962 | verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS)); |
| 2966 | 2963 | ||
| 2967 | /* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at compile time. */ | 2964 | /* 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 <http://www.gnu.org/licenses/>. */ | |||
| 30 | #endif | 30 | #endif |
| 31 | 31 | ||
| 32 | #include <setjmp.h> | 32 | #include <setjmp.h> |
| 33 | |||
| 33 | #include <c-ctype.h> | 34 | #include <c-ctype.h> |
| 35 | #include <flexmember.h> | ||
| 34 | 36 | ||
| 35 | #include "lisp.h" | 37 | #include "lisp.h" |
| 36 | #include "frame.h" | 38 | #include "frame.h" |
| @@ -3347,7 +3349,7 @@ xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket) | |||
| 3347 | if (bucket < 0) | 3349 | if (bucket < 0) |
| 3348 | bucket = xpm_color_bucket (color_name); | 3350 | bucket = xpm_color_bucket (color_name); |
| 3349 | 3351 | ||
| 3350 | nbytes = offsetof (struct xpm_cached_color, name) + strlen (color_name) + 1; | 3352 | nbytes = FLEXSIZEOF (struct xpm_cached_color, name, strlen (color_name) + 1); |
| 3351 | p = xmalloc (nbytes); | 3353 | p = xmalloc (nbytes); |
| 3352 | strcpy (p->name, color_name); | 3354 | strcpy (p->name, color_name); |
| 3353 | p->color = *color; | 3355 | p->color = *color; |
| @@ -8328,8 +8330,8 @@ static struct animation_cache * | |||
| 8328 | imagemagick_create_cache (char *signature) | 8330 | imagemagick_create_cache (char *signature) |
| 8329 | { | 8331 | { |
| 8330 | struct animation_cache *cache | 8332 | struct animation_cache *cache |
| 8331 | = xmalloc (offsetof (struct animation_cache, signature) | 8333 | = xmalloc (FLEXSIZEOF (struct animation_cache, signature, |
| 8332 | + strlen (signature) + 1); | 8334 | strlen (signature) + 1)); |
| 8333 | cache->wand = 0; | 8335 | cache->wand = 0; |
| 8334 | cache->index = 0; | 8336 | cache->index = 0; |
| 8335 | cache->next = 0; | 8337 | 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 | |||
| 1429 | Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER]; | 1429 | Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER]; |
| 1430 | }; | 1430 | }; |
| 1431 | 1431 | ||
| 1432 | /* C11 prohibits alignof (struct Lisp_Vector), so compute it manually. */ | ||
| 1433 | enum | ||
| 1434 | { | ||
| 1435 | ALIGNOF_STRUCT_LISP_VECTOR | ||
| 1436 | = alignof (union { struct vectorlike_header a; Lisp_Object b; }) | ||
| 1437 | }; | ||
| 1438 | |||
| 1439 | /* A boolvector is a kind of vectorlike, with contents like a string. */ | 1432 | /* A boolvector is a kind of vectorlike, with contents like a string. */ |
| 1440 | 1433 | ||
| 1441 | struct Lisp_Bool_Vector | 1434 | 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 <http://www.gnu.org/licenses/>. */ | |||
| 88 | #endif | 88 | #endif |
| 89 | 89 | ||
| 90 | #include <c-ctype.h> | 90 | #include <c-ctype.h> |
| 91 | #include <flexmember.h> | ||
| 91 | #include <sig2str.h> | 92 | #include <sig2str.h> |
| 92 | #include <verify.h> | 93 | #include <verify.h> |
| 93 | 94 | ||
| @@ -3807,8 +3808,8 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3807 | struct gaicb gaicb; | 3808 | struct gaicb gaicb; |
| 3808 | struct addrinfo hints; | 3809 | struct addrinfo hints; |
| 3809 | char str[FLEXIBLE_ARRAY_MEMBER]; | 3810 | char str[FLEXIBLE_ARRAY_MEMBER]; |
| 3810 | } *req = xmalloc (offsetof (struct req, str) | 3811 | } *req = xmalloc (FLEXSIZEOF (struct req, str, |
| 3811 | + hostlen + 1 + portstringlen + 1); | 3812 | hostlen + 1 + portstringlen + 1)); |
| 3812 | dns_request = &req->gaicb; | 3813 | dns_request = &req->gaicb; |
| 3813 | dns_request->ar_name = req->str; | 3814 | dns_request->ar_name = req->str; |
| 3814 | dns_request->ar_service = req->str + hostlen + 1; | 3815 | dns_request->ar_service = req->str + hostlen + 1; |