<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 - False positive on std::data(std::string&)"
   href="https://bugs.llvm.org/show_bug.cgi?id=44675">44675</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>False positive on std::data(std::string&)
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>7.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>cassio.neri@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dcoughlin@apple.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The below presents 3 versions of a function named copy which attempts to get a
pointer to the first element of a string.

VERSION == 1: uses std::data(std::string&) and gives a false positive on "Use
of memory after it is freed"

VERSION == 2: uses str::string::data() and no warning is issued.

VERSION == 3: uses an inline copy-and-pasted implementation of libstdc++'s
std::data. Again, no warning is issued.

<FILE name="main.cpp">
        #include <string>
        #include <cstring>
        #include <iterator>

        namespace foo {

        // Copy-and-pasted from libstdc++
        template <typename _Container>
        constexpr auto
        data(_Container& __cont) noexcept(noexcept(__cont.data()))
        -> decltype(__cont.data())
        { return __cont.data(); }

        }

        #define VERSION 1

        void copy(std::string& tgt, char* src, unsigned n) {

                tgt.resize(n);

                #if VERSION == 1
                        std::memcpy(std::data(tgt), src, n); // scan-build:
warning: Use of memory after it is freed
                #elif VERSION == 2
                        std::memcpy(tgt.data(), src, n);     // scan-build: No
bugs found.
                #else
                        std::memcpy(foo::data(tgt), src, n); // scan-build: No
bugs found.
                #endif
        }

        void test(char* src, unsigned n) {
                std::string tgt;
                copy(tgt, src, n);
        }
</FILE>

Analysed with:
        $ scan-build clang++ -g -std=c++17 -c main.cpp -o main.o

FWIW:

a) Obviously, VERSION 2 is a good workaround. However, in my real code (not in
this self-contained, reduced test case) the function is a template on T and T
== std::string is just one possible instantiation. (Among others like
std::vector<char>, char[N], ... for which no warning is issued) Therefore,
fixing the false positive would be helpful to generic code.

b) In C++17 std::string::data returns char* in contrast to const char* as in
previous standards.</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>