<html>
<head>
<base href="https://llvm.org/bugs/" />
</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 --- - Overlapping memcpy in SmallVector.h (via SmallString::operator=())"
href="https://llvm.org/bugs/show_bug.cgi?id=25293">25293</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Overlapping memcpy in SmallVector.h (via SmallString::operator=())
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</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>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Support Libraries
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>mattipee@yahoo.co.uk
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>clang version 3.8.0 (<a href="http://llvm.org/git/clang.git">http://llvm.org/git/clang.git</a>
3a551363c4cdd54c939cd9cc969d45bc8f8e93d8) (<a href="http://llvm.org/git/llvm.git">http://llvm.org/git/llvm.git</a>
ca4c86d2fd31ba4c23b9f3028e4f812713f230c6)
Target: x86_64-unknown-linux-gnu
Thread model: posix
==26255== Memcheck, a memory error detector
==26255== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==26255== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright
info
==26255== Command: clang++ --std=c++14 -I/usr/local/include -E -o
/tmp/56294cc2_0xffefffa30/testcase.ii /tmp/56294cc2_0xffefffa30/testcase.cpp
==26255==
==26255== Source and destination overlap in memcpy(0xffeffe7c0, 0xffeffe7c0,
42)
==26255== at 0x6D140CD: memcpy@@GLIBC_2.14 (vg_replace_strmem.c:1018)
==26255== by 0x9E5724:
_ZN4llvm23SmallVectorTemplateBaseIcLb1EE18uninitialized_copyIKccEEvPT_S5_PT0_PNSt9enable_ifIXsr3std7is_sameINSt12remove_constIS4_E4typeES6_EE5valueEvE4typeE
(SmallVector.h:328)
==26255== by 0x9E55AA: void llvm::SmallVectorImpl<char>::append<char
const*>(char const*, char const*) (SmallVector.h:430)
==26255== by 0x9E586F: void llvm::SmallString<128u>::append<char
const*>(char const*, char const*) (SmallString.h:75)
==26255== by 0x9E5824: llvm::SmallString<128u>::operator+=(llvm::StringRef)
(SmallString.h:286)
==26255== by 0x9E5247: llvm::SmallString<128u>::operator=(llvm::StringRef)
(in /.../build-debug/bin/clang-3.8)
==26255== by 0x9DE90D: SetInstallDir(llvm::SmallVectorImpl<char const*>&,
clang::driver::Driver&, bool) (driver.cpp:293)
==26255== by 0x9DD74A: main (driver.cpp:435)
Suggested change:
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index d1062ac..d6f13f3 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -324,7 +324,7 @@ protected:
// iterators): std::uninitialized_copy optimizes to memmove, but we can
// use memcpy here. Note that I and E are iterators and thus might be
// invalid for memcpy if they are equal.
- if (I != E)
+ if (I != E && I != Dest)
memcpy(Dest, I, (E - I) * sizeof(T));
}
Looking further, I guess it's ok for SmallString to clear() the underlying
SmallVector in the assignment operator. Even though the "StringRef RHS"
returned by parent_path still points into the data being cleared, it's not
going to go anywhere as a parent path is always going to be shorter. Either
way, the overlapping memcpy could be avoided as above.
driver.cpp:293
InstalledPath = llvm::sys::path::parent_path(InstalledPath);
SmallString.h:280-288
const SmallString &operator=(StringRef RHS) {
this->clear();
return *this += RHS;
}
SmallString &operator+=(StringRef RHS) {
this->append(RHS.begin(), RHS.end());
return *this;
}</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>