Skip to content

Commit

Permalink
compat/obstack: fix -Wcast-function-type warnings
Browse files Browse the repository at this point in the history
GCC 8 introduced the new -Wcast-function-type warning, which is
implied by -Wextra (which, in turn is enabled in our DEVELOPER flags).
When building Git with GCC 8 and this warning enabled on a non-glibc
platform [1], one is greeted with a screenful of compiler
warnings/errors:

  compat/obstack.c: In function '_obstack_begin':
  compat/obstack.c:162:17: error: cast between incompatible function types from 'void * (*)(long int)' to 'struct _obstack_chunk * (*)(void *, long int)' [-Werror=cast-function-type]
     h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
                   ^
  compat/obstack.c:163:16: error: cast between incompatible function types from 'void (*)(void *)' to 'void (*)(void *, struct _obstack_chunk *)' [-Werror=cast-function-type]
     h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
                  ^
  compat/obstack.c:116:8: error: cast between incompatible function types from 'struct _obstack_chunk * (*)(void *, long int)' to 'struct _obstack_chunk * (*)(long int)' [-Werror=cast-function-type]
      : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
          ^
  compat/obstack.c:168:22: note: in expansion of macro 'CALL_CHUNKFUN'
     chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
                        ^~~~~~~~~~~~~
  <snip>

'struct obstack' stores pointers to two functions to allocate and free
"chunks", and depending on how obstack is used, these functions take
either one parameter (like standard malloc() and free() do; this is
how we use it in 'kwset.c') or two parameters.  Presumably to reduce
memory footprint, a single field is used to store the function pointer
for both signatures, and then it's casted to the appropriate signature
when the function pointer is accessed.  These casts between function
pointers with different number of parameters are what trigger those
compiler errors.

Modify 'struct obstack' to use unions to store function pointers with
different signatures, and then use the union member with the
appropriate signature when accessing these function pointers.  This
eliminates the need for those casts, and thus avoids this compiler
error.

[1] Compiling 'compat/obstack.c' on a platform with glibc is sort of
    a noop, see the comment before '#  define ELIDE_CODE', so this is
    not an issue on common Linux distros.

Signed-off-by: SZEDER Gábor <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
szeder authored and gitster committed Jan 17, 2019
1 parent 268fbcd commit 764473d
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 15 deletions.
17 changes: 9 additions & 8 deletions compat/obstack.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);

# define CALL_CHUNKFUN(h, size) \
(((h) -> use_extra_arg) \
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
: (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
? (*(h)->chunkfun.extra) ((h)->extra_arg, (size)) \
: (*(h)->chunkfun.plain) ((size)))

# define CALL_FREEFUN(h, old_chunk) \
do { \
if ((h) -> use_extra_arg) \
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
(*(h)->freefun.extra) ((h)->extra_arg, (old_chunk)); \
else \
(*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
(*(h)->freefun.plain) ((old_chunk)); \
} while (0)


Expand Down Expand Up @@ -159,8 +159,8 @@ _obstack_begin (struct obstack *h,
size = 4096 - extra;
}

h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
h->chunkfun.plain = chunkfun;
h->freefun.plain = freefun;
h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->use_extra_arg = 0;
Expand Down Expand Up @@ -206,8 +206,9 @@ _obstack_begin_1 (struct obstack *h, int size, int alignment,
size = 4096 - extra;
}

h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
h->chunkfun.extra = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
h->freefun.extra = (void (*) (void *, struct _obstack_chunk *)) freefun;

h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->extra_arg = arg;
Expand Down
18 changes: 11 additions & 7 deletions compat/obstack.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,15 @@ struct obstack /* control current object in current chunk */
void *tempptr;
} temp; /* Temporary for some macros. */
int alignment_mask; /* Mask of alignment for each object. */
/* These prototypes vary based on `use_extra_arg', and we use
casts to the prototypeless function type in all assignments,
but having prototypes here quiets -Wstrict-prototypes. */
struct _obstack_chunk *(*chunkfun) (void *, long);
void (*freefun) (void *, struct _obstack_chunk *);
/* These prototypes vary based on `use_extra_arg'. */
union {
void *(*plain) (long);
struct _obstack_chunk *(*extra) (void *, long);
} chunkfun;
union {
void (*plain) (void *);
void (*extra) (void *, struct _obstack_chunk *);
} freefun;
void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
unsigned maybe_empty_object:1;/* There is a possibility that the current
Expand Down Expand Up @@ -235,10 +239,10 @@ extern void (*obstack_alloc_failed_handler) (void);
(void (*) (void *, void *)) (freefun), (arg))

#define obstack_chunkfun(h, newchunkfun) \
((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
((h)->chunkfun.extra = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))

#define obstack_freefun(h, newfreefun) \
((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
((h)->freefun.extra = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))

#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))

Expand Down

0 comments on commit 764473d

Please sign in to comment.