[llvm-bugs] [Bug 44114] New: Getting an "uninitialized value" report with involvement of volatile ...
via llvm-bugs
llvm-bugs at lists.llvm.org
Fri Nov 22 04:50:31 PST 2019
https://bugs.llvm.org/show_bug.cgi?id=44114
Bug ID: 44114
Summary: Getting an "uninitialized value" report with
involvement of volatile ...
Product: clang
Version: 9.0
Hardware: PC
OS: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: Static Analyzer
Assignee: dcoughlin at apple.com
Reporter: o.schneider at precitec-optronik.de
CC: dcoughlin at apple.com, llvm-bugs at lists.llvm.org
Created attachment 22855
--> https://bugs.llvm.org/attachment.cgi?id=22855&action=edit
The minimal working example as .cpp file plus a GNUmakefile and the output of a
run of CSA (9.0.0) on it.
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 <cstdio>
#include <cstdint>
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
0399d5a9682b3cef71c653373e38890c63c4c365 (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).
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20191122/a87b2a05/attachment.html>
More information about the llvm-bugs
mailing list