[Umbrella] Teach RegionStore about binding extents. (original) (raw)
| Bugzilla Link | 44114 |
|---|---|
| Version | 9.0 |
| OS | Linux |
| Attachments | The minimal working example as .cpp file plus a GNUmakefile and the output of a run of CSA (9.0.0) on it. |
| Reporter | LLVM Bugzilla Contributor |
| CC | @devincoughlin,@haoNoQ |
Extended Description
Hi,
admittedly neither I nor my colleagues are sure whether this is a false positive of the static analyzer (CSA) or a misconception of sorts on our part.
So the issue is in the attached (self-contained) example. I am pasting it here for reference:
#include
#include
struct device_registers
{
uint32_t n1;
uint32_t n2;
uint32_t n3;
uint32_t n4;
uint32_t n5;
} attribute((packed));
static_assert(
20 == sizeof(struct device_registers),
"unexpected struct size"
);
static void CopyDeviceRegisters(
struct device_registers volatile& dest,
struct device_registers volatile* src
)
{
dest.n1 = src->n1;
dest.n2 = src->n2;
dest.n3 = src->n3;
dest.n4 = src->n4;
dest.n5 = src->n5;
}
// this is a pretend process_bytes() from boost/crc.hpp
// (where it's a member function)
void process_bytes(void const* buffer, size_t byte_count)
{
// "checksum creation"
unsigned char const* const b = static_cast<unsigned char const*>(buffer);
for(size_t i = 0; i < byte_count; i++)
{
printf("%02X ", b[i]);
}
printf("\n");
}
int main(int, char**)
{
// in our code this is a uio mapping
struct device_registers mock{};
struct device_registers volatile* mapped_regs = &mock;
// purpose is to get a copy of the volatile mapping to compute a
// checksum
struct device_registers shadow;
CopyDeviceRegisters(shadow, mapped_regs);
// now we merely need to read from the (shadow) struct to mimick
// what the real process_bytes() would do ...
process_bytes(&shadow, sizeof(shadow));
return 0;
}
This code is representative of the issue we're seeing and the attached file includes a run of CSA over that MWE.
After some tinkering it appears clear that the volatile nature of mapped_regs and the arguments to CopyDeviceRegisters() are an issue here.
My guess is that CSA "reasons" that - due to the volatility - the data in mapped_regs isn't initialized and that fact isn't changed by CopyDeviceRegisters().
How would we have to convey it to CSA/Clang that we deem local variable (shadow) initialized after the call to CopyDeviceRegisters()? ... or is this a false positive which we should not care about?
Thank you for reading and with best regards,
Oliver
PS: After unpacking the MWE you should be able to use 'make analyze' which should 'make clean' (implicitly), followed by running 'make mwe' via scan-build. So the assumption is that scan-build is in the PATH and works.
We're working with a Clang that I build myself from 0399d5a (which should be the 9.0.0 release tag or at least was at one point) which targets x86_64-unknown-linux-gnu on a vanilla Ubuntu 14.04 (yes, I built it on a pristine LXD image of Ubuntu 14.04, so there isn't any "contamination" beyond build dependencies).