mercredi 11 août 2021

clang-tidy: Assigned value is garbage or undefined when accessing raw memory of an array or struct

When running clang-tidy I get an warning when accessing an address of an array:

src/main.cpp:10:9: warning: Assigned value is garbage or undefined [clang-analyzer-core.uninitialized.Assign]
    sum += *(addr++);
        ^

The code is stripped down from a more complex example (full checksum implementation - taken from RFC1071 - and using a struct instead of the array):

#include <iostream>
#include <cstring>

static uint16_t csum(void* buffer, size_t size)
{
  uint32_t sum = 0;
  auto *addr = static_cast<uint16_t *>(buffer);
  while( size > 1 )  {
    /*  This is the inner loop */
    sum += *(addr++);
    size -= sizeof(*addr);
  }
  return static_cast<uint16_t>(~sum);
}

int main (int argc, char* argv[])
{
  uint32_t test[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  //memset(&test, 0, sizeof(test));
  uint16_t sum = csum(test, sizeof(test));
  std::cout << argc << " " << argv[0] << " " << sum << " " << sizeof(test) << std::endl;
}

clang-tidy shows this value is garbage or undefined whenever the array is of type uint32_t or uint64_t (or using any custom packed struct) but not when being uint16_t or uint8_t - some alignment issue?

But at least for me more surprising - the warning is not shown with uint32_t, uint64_t or any custom packed struct when uncommenting the memset - why? Wasn't it proper initialized before? Do I hit some area, where C/C++ isn't defined properly?

Or will clang-tidy analyze every usage of csum - also those where the size of the buffer does not match the size variable?

Aucun commentaire:

Enregistrer un commentaire