<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>