<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><br>
</p>
<br>
<div class="moz-cite-prefix">On 6/8/17 11:05 AM, don hinton via
cfe-dev wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CAL2T-v5F1KvDXwS0qEHU=3ODivr+ug9YSXEomyYcvfZEDkDh1Q@mail.gmail.com">
<div dir="ltr">
<div><font face="monospace, monospace">I'm seeing memory
corruption when I use a literal string and std::string in a
ternary (?:) expression. If I change ss to ss.c_str() on
line 5, the corruption goes away. [1] is an AST diff, which
might help explain it.</font></div>
<div><font face="monospace, monospace"><br>
</font></div>
<div><font face="monospace, monospace">Although clang doesn't
give me an error or warning, is this code legal, or is this
a bug?</font></div>
</div>
</blockquote>
<font face="monospace, monospace">No, this is a bug in x.cpp. the
common type between "noexcept" and std::string is std::string,
which means that the conditional expression materializes a
temporary string to hold the "noexcept" and binds it to the
StringRef when the true branch is taken. Clang doesn't warn here
because it isn't smart enough to know what StringRef is doing. You
can try rewriting this as:<br>
<br>
llvm::StringRef Ref = "noexcept";<br>
if (true || whatever)<br>
Ref = some_std_string;<br>
<br>
</font>
<blockquote type="cite"
cite="mid:CAL2T-v5F1KvDXwS0qEHU=3ODivr+ug9YSXEomyYcvfZEDkDh1Q@mail.gmail.com">
<div dir="ltr">
<div><font face="monospace, monospace"><br>
</font></div>
<div><font face="monospace, monospace">thanks...</font></div>
<div><font face="monospace, monospace">don</font></div>
<div><font face="monospace, monospace"><br>
</font></div>
<div><font face="monospace, monospace"><br>
</font></div>
<div>
<div><font face="monospace, monospace">$ grep -n "." x.cpp</font></div>
<div><font face="monospace, monospace">1:#include
"llvm/ADT/StringRef.h"</font></div>
<div><font face="monospace, monospace">3:int main() {</font></div>
<div><font face="monospace, monospace">4: const std::string
ss;</font></div>
<div><font face="monospace, monospace">5: llvm::StringRef Ref
= true ? "noexcept" : ss;</font></div>
<div><font face="monospace, monospace">6: std::string s =
Ref;</font></div>
<div><font face="monospace, monospace">7: return 0;</font></div>
<div><font face="monospace, monospace">8:}</font></div>
</div>
<div><font face="monospace, monospace"><br>
</font></div>
<div><font face="monospace, monospace">$
../../4.0.0/build/Release/bin/<wbr>clang++ x.cpp -O1 -g
-fsanitize=address -fno-omit-frame-pointer -std=c++11 -I
../../llvm/include/ -I include</font></div>
<div><font face="monospace, monospace"><br>
</font></div>
<div>
<div><font face="monospace, monospace">$ ./a.out</font></div>
<div><font face="monospace, monospace">==============================<wbr>==============================<wbr>=====</font></div>
<div><font face="monospace, monospace">==14769==ERROR:
AddressSanitizer: heap-use-after-free on address
0x604000000068 at pc 0x0000004651b2 bp 0x7ffcc5b3a7d0 sp
0x7ffcc5b39f80</font></div>
<div><font face="monospace, monospace">READ of size 8 at
0x604000000068 thread T0</font></div>
<div><font face="monospace, monospace"> #0 0x4651b1 in
__interceptor_memcpy.part.36
/home/d80049854/projects/clang<wbr>/4.0.0/llvm/projects/compilerr<wbr>t/lib/asan/../sanitizer_<wbr>common/sanitizer_common_<wbr>interceptors.inc:655</font></div>
<div><font face="monospace, monospace"> #1 0x7f00fe4d10ed
(/usr/lib/x86_64-linux-gnu/li<wbr>bstdc++.so.6+0xc40ed)</font></div>
<div><font face="monospace, monospace"> #2 0x7f00fe4d298a
in std::basic_string<char,
std::char_traits<char>, std::allocator<char>
>::basic_string(char const*, unsigned long,
std::allocator<char> const&)
(/usr/lib/x86_64-linux-gnu/lib<wbr>stdc++.so.6+0xc598a)</font></div>
<div><font face="monospace, monospace"> #3 0x50d3bc in
llvm::StringRef::str() const
/home/d80049854/projects/clang<wbr>/build/Debug/../../llvm/includ<wbr>e/llvm/ADT/StringRef.h:230:14</font></div>
<div><font face="monospace, monospace"> #4 0x50d2cd in
llvm::StringRef::operator std::string() const
/home/d80049854/projects/clang<wbr>/build/Debug/../../llvm/includ<wbr>e/llvm/ADT/StringRef.h:257:14</font></div>
<div><font face="monospace, monospace"> #5 0x50d0aa in main
/home/d80049854/projects/clang<wbr>/build/Debug/x.cpp:6:19</font></div>
<div><font face="monospace, monospace"> #6 0x7f00fd522f44
in __libc_start_main (/lib/x86_64-linux-gnu/libc.so<wbr>.6+0x21f44)</font></div>
<div><font face="monospace, monospace"> #7 0x41a10b in
_start (/home/d80049854/projects/clan<wbr>g/build/Debug/a.out+0x41a10b)</font></div>
</div>
<div><font face="monospace, monospace"><br>
</font></div>
<div>
<div><font face="monospace, monospace">0x604000000068 is
located 24 bytes inside of 33-byte region
[0x604000000050,0x604000000071<wbr>)</font></div>
<div><font face="monospace, monospace">freed by thread T0
here:</font></div>
<div><font face="monospace, monospace"> #0 0x5098b0 in
operator delete(void*) /home/d80049854/projects/clang<wbr>/4.0.0/llvm/projects/compiler-<wbr>rt/lib/asan/asan_new_delete.<wbr>cc:126</font></div>
<div><font face="monospace, monospace"> #1 0x7f00fe4d11cd
in std::basic_string<char,
std::char_traits<char>, std::allocator<char>
>::~basic_string() (/usr/lib/x86_64-linux-gnu/lib<wbr>stdc++.so.6+0xc41cd)</font></div>
<div><font face="monospace, monospace"> #2 0x7f00fd522f44
in __libc_start_main (/lib/x86_64-linux-gnu/libc.so<wbr>.6+0x21f44)</font></div>
<div><font face="monospace, monospace"><br>
</font></div>
<div><font face="monospace, monospace">previously allocated by
thread T0 here:</font></div>
<div><font face="monospace, monospace"> #0 0x508b70 in
operator new(unsigned long) /home/d80049854/projects/clang<wbr>/4.0.0/llvm/projects/compiler-<wbr>rt/lib/asan/asan_new_delete.<wbr>cc:82</font></div>
<div><font face="monospace, monospace"> #1 0x7f00fe4d0f68
in std::string::_Rep::_S_create(u<wbr>nsigned long,
unsigned long, std::allocator<char> const&)
(/usr/lib/x86_64-linux-gnu/lib<wbr>stdc++.so.6+0xc3f68)</font></div>
<div><font face="monospace, monospace"><br>
</font></div>
<div><font face="monospace, monospace">SUMMARY:
AddressSanitizer: heap-use-after-free
/home/d80049854/projects/clang<wbr>/4.0.0/llvm/projects/compiler-<wbr>rt/lib/asan/../sanitizer_<wbr>common/sanitizer_common_<wbr>interceptors.inc:655
in __interceptor_memcpy.part.36</font></div>
<div><font face="monospace, monospace">Shadow bytes around the
buggy address:</font></div>
<div><font face="monospace, monospace"> 0x0c087fff7fb0: 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00</font></div>
<div><font face="monospace, monospace"> 0x0c087fff7fc0: 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00</font></div>
<div><font face="monospace, monospace"> 0x0c087fff7fd0: 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00</font></div>
<div><font face="monospace, monospace"> 0x0c087fff7fe0: 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00</font></div>
<div><font face="monospace, monospace"> 0x0c087fff7ff0: 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00</font></div>
<div><font face="monospace, monospace">=>0x0c087fff8000: fa
fa 00 00 00 00 00 01 fa fa fd fd fd[fd]fd fa</font></div>
<div><font face="monospace, monospace"> 0x0c087fff8010: fa fa
00 00 00 00 01 fa fa fa fa fa fa fa fa fa</font></div>
<div><font face="monospace, monospace"> 0x0c087fff8020: fa fa
fa fa fa fa fa fa fa fa fa fa fa fa fa fa</font></div>
<div><font face="monospace, monospace"> 0x0c087fff8030: fa fa
fa fa fa fa fa fa fa fa fa fa fa fa fa fa</font></div>
<div><font face="monospace, monospace"> 0x0c087fff8040: fa fa
fa fa fa fa fa fa fa fa fa fa fa fa fa fa</font></div>
<div><font face="monospace, monospace"> 0x0c087fff8050: fa fa
fa fa fa fa fa fa fa fa fa fa fa fa fa fa</font></div>
<div><font face="monospace, monospace">Shadow byte legend (one
shadow byte represents 8 application bytes):</font></div>
<div><font face="monospace, monospace"> Addressable:
00</font></div>
<div><font face="monospace, monospace"> Partially
addressable: 01 02 03 04 05 06 07</font></div>
<div><font face="monospace, monospace"> Heap left redzone:
fa</font></div>
<div><font face="monospace, monospace"> Freed heap region:
fd</font></div>
<div><font face="monospace, monospace"> Stack left redzone:
f1</font></div>
<div><font face="monospace, monospace"> Stack mid redzone:
f2</font></div>
<div><font face="monospace, monospace"> Stack right redzone:
f3</font></div>
<div><font face="monospace, monospace"> Stack after return:
f5</font></div>
<div><font face="monospace, monospace"> Stack use after
scope: f8</font></div>
<div><font face="monospace, monospace"> Global redzone:
f9</font></div>
<div><font face="monospace, monospace"> Global init order:
f6</font></div>
<div><font face="monospace, monospace"> Poisoned by user:
f7</font></div>
<div><font face="monospace, monospace"> Container overflow:
fc</font></div>
<div><font face="monospace, monospace"> Array cookie:
ac</font></div>
<div><font face="monospace, monospace"> Intra object redzone:
bb</font></div>
<div><font face="monospace, monospace"> ASan internal:
fe</font></div>
<div><font face="monospace, monospace"> Left alloca redzone:
ca</font></div>
<div><font face="monospace, monospace"> Right alloca redzone:
cb</font></div>
<div><font face="monospace, monospace">==14769==ABORTING</font></div>
</div>
<div><font face="monospace, monospace"><br>
</font></div>
<div><font face="monospace, monospace">1. AST diff:</font></div>
<div><font face="monospace, monospace">< uses ss</font></div>
<div><font face="monospace, monospace">> uses ss.c_str()</font></div>
<div><font face="monospace, monospace"><br>
</font></div>
<div><font face="monospace, monospace" size="1">
<div>49566c49566</div>
<div>< | | |-CXXConstructorDecl 0xXXXXXXX
<line:3010:7, col:XX> col:XX used basic_string 'void
(const char *, const class std::allocator<char>
&)'</div>
<div>---</div>
<div>> | | |-CXXConstructorDecl 0xXXXXXXX
<line:3010:7, col:XX> col:XX basic_string 'void
(const char *, const class std::allocator<char>
&)'</div>
<div>49568,49573c49568</div>
<div>< | | | `-ParmVarDecl 0xXXXXXXX <col:XX,
col:XX> col:XX __a 'const class
std::allocator<char> &' cinit</div>
<div>< | | | `-ExprWithCleanups 0xXXXXXXX <col:XX,
col:XX> 'const class std::allocator<char>':'const
class std::allocator<char>' lvalue</div>
<div>< | | | `-MaterializeTemporaryExpr 0xXXXXXXX
<col:XX, col:XX> 'const class
std::allocator<char>':'const class
std::allocator<char>' lvalue</div>
<div>< | | | `-ImplicitCastExpr 0xXXXXXXX
<col:XX, col:XX> 'const class
std::allocator<char>':'const class
std::allocator<char>' <NoOp></div>
<div>< | | | `-CXXBindTemporaryExpr 0xXXXXXXX
<col:XX, col:XX> 'class
std::allocator<char>':'class
std::allocator<char>' (CXXTemporary 0xXXXXXXX)</div>
<div>< | | | `-CXXTemporaryObjectExpr 0xXXXXXXX
<col:XX, col:XX> 'class
std::allocator<char>':'class
std::allocator<char>' 'void (void) throw()'</div>
<div>---</div>
<div>> | | | `-ParmVarDecl 0xXXXXXXX <col:XX,
col:XX> col:XX __a 'const class
std::allocator<char> &'</div>
<div>108945c108940</div>
<div>< | | |-CXXConstructorDecl 0xXXXXXXX
<../../llvm/include/llvm/<wbr>Support/Compiler.h:194:38,
../../llvm/include/llvm/ADT/<wbr>StringRef.h:96:49>
line:95:18 used StringRef 'void (const std::string &)'</div>
<div>---</div>
<div>> | | |-CXXConstructorDecl 0xXXXXXXX
<../../llvm/include/llvm/<wbr>Support/Compiler.h:194:38,
../../llvm/include/llvm/ADT/<wbr>StringRef.h:96:49>
line:95:18 StringRef 'void (const std::string &)'</div>
<div>111747,111765c111742,111749</div>
<div>< | `-CXXConstructExpr 0xXXXXXXX
<col:XX, col:XX> 'llvm::StringRef':'class
llvm::StringRef' 'void (const std::string &)'</div>
<div>< | `-MaterializeTemporaryExpr
0xXXXXXXX <col:XX, col:XX> 'const
std::string':'const class std::basic_string<char>'
lvalue</div>
<div>< | `-ConditionalOperator
0xXXXXXXX <col:XX, col:XX> 'const
std::string':'const class std::basic_string<char>'</div>
<div>< | |-CXXBoolLiteralExpr
0xXXXXXXX <col:XX> '_Bool' true</div>
<div>< | |-CXXBindTemporaryExpr
0xXXXXXXX <col:XX> 'const std::string':'const class
std::basic_string<char>' (CXXTemporary 0xXXXXXXX)</div>
<div>< | | `-CXXConstructExpr
0xXXXXXXX <col:XX> 'const std::string':'const class
std::basic_string<char>' 'void (const class
std::basic_string<char> &)' elidable</div>
<div>< | |
`-MaterializeTemporaryExpr 0xXXXXXXX <col:XX> 'const
std::string':'const class std::basic_string<char>'
lvalue</div>
<div>< | | `-CXXBindTemporaryExpr
0xXXXXXXX <col:XX> 'const std::string':'const class
std::basic_string<char>' (CXXTemporary 0xXXXXXXX)</div>
<div>< | | `-CXXConstructExpr
0xXXXXXXX <col:XX> 'const std::string':'const class
std::basic_string<char>' 'void (class
std::basic_string<char> &&) noexcept'
elidable</div>
<div>< | |
`-MaterializeTemporaryExpr 0xXXXXXXX <col:XX>
'std::string':'class std::basic_string<char>' xvalue</div>
<div>< | |
`-CXXBindTemporaryExpr 0xXXXXXXX <col:XX>
'std::string':'class std::basic_string<char>'
(CXXTemporary 0xXXXXXXX)</div>
<div>< | |
`-ImplicitCastExpr 0xXXXXXXX <col:XX>
'std::string':'class std::basic_string<char>'
<ConstructorConversion></div>
<div>< | |
`-CXXConstructExpr 0xXXXXXXX <col:XX>
'std::string':'class std::basic_string<char>' 'void
(const char *, const class std::allocator<char>
&)'</div>
<div>< | |
|-ImplicitCastExpr 0xXXXXXXX <col:XX> 'const char *'
<ArrayToPointerDecay></div>
<div>< | | |
`-StringLiteral 0xXXXXXXX <col:XX> 'const char [9]'
lvalue "noexcept"</div>
<div>< | |
`-CXXDefaultArgExpr 0xXXXXXXX <<invalid sloc>>
'const class std::allocator<char>':'const class
std::allocator<char>' lvalue</div>
<div>< | `-CXXBindTemporaryExpr
0xXXXXXXX <col:XX> 'const std::string':'const class
std::basic_string<char>' (CXXTemporary 0xXXXXXXX)</div>
<div>< | `-CXXConstructExpr
0xXXXXXXX <col:XX> 'const std::string':'const class
std::basic_string<char>' 'void (const class
std::basic_string<char> &)'</div>
<div>< | `-DeclRefExpr 0xXXXXXXX
<col:XX> 'const std::string':'const class
std::basic_string<char>' lvalue Var 0xXXXXXXX 'ss'
'const std::string':'const class
std::basic_string<char>'</div>
<div>---</div>
<div>> | `-CXXConstructExpr 0xXXXXXXX
<col:XX, col:XX> 'llvm::StringRef':'class
llvm::StringRef' 'void (const char *)'</div>
<div>> | `-ConditionalOperator 0xXXXXXXX
<col:XX, col:XX> 'const char *'</div>
<div>> | |-CXXBoolLiteralExpr 0xXXXXXXX
<col:XX> '_Bool' true</div>
<div>> | |-ImplicitCastExpr 0xXXXXXXX
<col:XX> 'const char *' <ArrayToPointerDecay></div>
<div>> | | `-StringLiteral 0xXXXXXXX
<col:XX> 'const char [9]' lvalue "noexcept"</div>
<div>> | `-CXXMemberCallExpr 0xXXXXXXX
<col:XX, col:XX> 'const char *'</div>
<div>> | `-MemberExpr 0xXXXXXXX
<col:XX, col:XX> '<bound member function
type>' .c_str 0xXXXXXXX</div>
<div>> | `-DeclRefExpr 0xXXXXXXX
<col:XX> 'const std::string':'const class
std::basic_string<char>' lvalue Var 0xXXXXXXX 'ss'
'const std::string':'const class
std::basic_string<char>'</div>
</font></div>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
cfe-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>
</pre>
</blockquote>
<br>
</body>
</html>