Skip to content
  • Gábor Szeder's avatar
    compat/obstack: fix -Wcast-function-type warnings · 764473d2
    Gábor Szeder authored and Junio C Hamano's avatar Junio C Hamano committed
    
    
    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: default avatarSZEDER Gábor <szeder.dev@gmail.com>
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    764473d2