-
Notifications
You must be signed in to change notification settings - Fork 38
Description
I'm using gcc 9.3.1 for arm, as bundled with STM32CubeIDE 1.6.1 (gcc version 9.3.1 20200408 (release) (GNU Tools for STM32 9-2020-q2-update.20201001-1621)). When trying to build with -O3 -Werror, I get a warning regarding the following code:
bool ConfigurationBlobFlash::BlobIsValid() const
{
Header header;
infra::Copy(infra::Head(blob, sizeof(header)), infra::MakeByteRange(header));
if (header.size + sizeof(Header) > blob.size())
return false;
where the warning is:
'header.services::ConfigurationBlobFlash::Header::size' may be used uninitialized in this function [-Werror=maybe-uninitialized]
76 | if (header.size + sizeof(Header) > blob.size())
| ~~~~~~~^~~~
I believe this warning to be correct and the code to be wrong: by using infra::MakeByteRange, header will be cast to an uint8_t*, which will be used by infra::Copy (which seems to call std::copy internally) to fill the byte range.
However, due to the strict aliasing rule, the compiler is free to assume that the uint8_t* being written does not overlap with header as they have different types. I suspect it might even be legal to optimize away the copy completely as there are no observable side-effects within the rules of the language.
My recommendation would be to simply do the following:
std::memcpy( &header, blob.begin(), sizeof( header ) );
which will yield the desired result with no risk of causing troubles.
(There are more constructs like these, it may be worthwhile to build with -O3 -Werror to locate them)