<div dir="ltr">Does this not break obvious/correct code like<br><br>StringRef src();<br>void sink(Twine);<br>...<br>sink(src());<br><br>Why not?<br><br><div class="gmail_quote"><div dir="ltr">On Fri, Nov 11, 2016 at 3:43 PM Vedant Kumar <<a href="mailto:vsk@apple.com">vsk@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">vsk created this revision.<br class="gmail_msg">
vsk added reviewers: aprantl, dblaikie.<br class="gmail_msg">
vsk added a subscriber: llvm-commits.<br class="gmail_msg">
<br class="gmail_msg">
Twine stores a *pointer to a StringRef*, not a StringRef. Taking the address of a StringRef rvalue could easily give us a dangling pointer.<br class="gmail_msg">
<br class="gmail_msg">
Adrian ran into this issue in the wild (see r286640). Deleting these constructors was his idea.<br class="gmail_msg">
<br class="gmail_msg">
llvm/clang are teeming with Twine abuse, so landing this patch right now would break all of our builds. If this patch looks OK, I can start weeding out the issues.<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
<a href="https://reviews.llvm.org/D26568" rel="noreferrer" class="gmail_msg" target="_blank">https://reviews.llvm.org/D26568</a><br class="gmail_msg">
<br class="gmail_msg">
Files:<br class="gmail_msg">
  include/llvm/ADT/Twine.h<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
Index: include/llvm/ADT/Twine.h<br class="gmail_msg">
===================================================================<br class="gmail_msg">
--- include/llvm/ADT/Twine.h<br class="gmail_msg">
+++ include/llvm/ADT/Twine.h<br class="gmail_msg">
@@ -370,6 +370,13 @@<br class="gmail_msg">
       assert(isValid() && "Invalid twine!");<br class="gmail_msg">
     }<br class="gmail_msg">
<br class="gmail_msg">
+    /// Do not construct from StringRef rvalues. Twine stores a *pointer to a<br class="gmail_msg">
+    /// StringRef*, not a StringRef. Taking the address of a StringRef rvalue<br class="gmail_msg">
+    /// could easily give us a dangling pointer.<br class="gmail_msg">
+    /*implicit*/ Twine(StringRef &&) = delete;<br class="gmail_msg">
+    /*implicit*/ Twine(const char *, StringRef &&) = delete;<br class="gmail_msg">
+    /*implicit*/ Twine(StringRef &&, const char *) = delete;<br class="gmail_msg">
+<br class="gmail_msg">
     /// Create a 'null' string, which is an empty string that always<br class="gmail_msg">
     /// concatenates to form another empty string.<br class="gmail_msg">
     static Twine createNull() {<br class="gmail_msg">
@@ -522,6 +529,8 @@<br class="gmail_msg">
     return Twine(LHS, RHS);<br class="gmail_msg">
   }<br class="gmail_msg">
<br class="gmail_msg">
+  inline Twine operator+(const char *, StringRef &&) = delete;<br class="gmail_msg">
+<br class="gmail_msg">
   /// Additional overload to guarantee simplified codegen; this is equivalent to<br class="gmail_msg">
   /// concat().<br class="gmail_msg">
<br class="gmail_msg">
@@ -529,6 +538,8 @@<br class="gmail_msg">
     return Twine(LHS, RHS);<br class="gmail_msg">
   }<br class="gmail_msg">
<br class="gmail_msg">
+  inline Twine operator+(StringRef &&, const char *) = delete;<br class="gmail_msg">
+<br class="gmail_msg">
   inline raw_ostream &operator<<(raw_ostream &OS, const Twine &RHS) {<br class="gmail_msg">
     RHS.print(OS);<br class="gmail_msg">
     return OS;<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
</blockquote></div></div>