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