Search code examples
c++gccnon-nullable

How to tell GCC that a pointer is non-null?


I'm trying to eliminate warnings from a block of code. It has this function:

 void OPN2_Reset(ym3438_t *chip, Bit32u rate, Bit32u clock)
 {
     Bit32u i, rateratio;
     rateratio = (Bit32u)chip->rateratio;
     memset(chip, 0, sizeof(ym3438_t));
     ...

This generates a build-time warning:

In function ‘void* memset(void*, int, size_t)’,
    inlined from ‘void Ym2612_NukedImpl::OPN2_Reset(ym3438_t*, Bit32u, Bit32u)’ at /home/logiclrd/zdoom/zmusic_build/zmusic/thirdparty/game-music-emu/gme/Ym2612_Nuked.cpp:1413:11,
    inlined from ‘void Ym2612_Nuked_Emu::reset()’ at /home/logiclrd/zdoom/zmusic_build/zmusic/thirdparty/game-music-emu/gme/Ym2612_Nuked.cpp:1842:45:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:59:33: warning: argument 1 null where non-null expected [-Wnonnull]
   59 |   return __builtin___memset_chk (__dest, __ch, __len,
      |          ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
   60 |                                  __glibc_objsize0 (__dest));
      |                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:59:33: note: in a call to built-in function ‘void* __builtin_memset(void*, int, long unsigned int)’

I've tried a whole bunch of searches to try to figure out how to tell the compiler that chip isn't NULL here, and I've tried various things and nothing seems to work.

// DOESN'T WORK
if (chip != NULL)
  memset(chip, 0, sizeof(ym3438_t));

// DOESN'T WORK
ym3438_t tmp;
ym3438_t *chip_nonnull = &tmp;
if (chip != NULL)
  chip_nonnull = chip;
memset(chip_nonnull, 0, sizeof(ym3438_t));

// DOESN'T WORK
assert(chip != NULL);
memset(chip, 0, sizeof(ym3438_t));

How do I make a call to memset only when chip is non-null, to avoid this warning? Or, how do I instruct the compiler to treat chip as non-null?


Solution

  • The pointer in question is null 100% of the time from the mentioned call stack.

    That is why gcc is so confident in telling you argument 1 null where non-null expected

    From the source:

    if ( !chip_r ) Ym2612_NukedImpl::OPN2_Reset( chip_r, static_cast<Bit32u>(prev_sample_rate), static_cast<Bit32u>(prev_clock_rate) );
    //   ^^^^^^^ if it's null...         pass it ^^^^^^