<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Getting an "uninitialized value" report with involvement of volatile ..."
   href="https://bugs.llvm.org/show_bug.cgi?id=44114">44114</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Getting an "uninitialized value" report with involvement of volatile ...
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>9.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Static Analyzer
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>dcoughlin@apple.com
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>o.schneider@precitec-optronik.de
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dcoughlin@apple.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=22855" name="attach_22855" title="The minimal working example as .cpp file plus a GNUmakefile and the output of a run of CSA (9.0.0) on it.">attachment 22855</a> <a href="attachment.cgi?id=22855&action=edit" title="The minimal working example as .cpp file plus a GNUmakefile and the output of a run of CSA (9.0.0) on it.">[details]</a></span>
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).</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>