From: David Blaikie Date: Thu, 8 Jul 2021 20:26:40 +0000 (-0700) Subject: PR51018: Disallow explicit construction of StringRef from SmallString due to ambiguit... X-Git-Tag: llvmorg-14-init~2006 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e2d30846327c7ec5cc9d2a46aa9bcd9c2c4eff93;p=platform%2Fupstream%2Fllvm.git PR51018: Disallow explicit construction of StringRef from SmallString due to ambiguity in C++23 See bug for full details, but basically there's an upcoming ambiguity in the conversion in `StringRef(SomeSmallString)` - either the implicit conversion operator (SmallString::operator StringRef) could be used, or the std::string_view range-based ctor (& then `StringRef(std::string_view)` would be used) To address this, make such a conversion invalid up-front - most uses are more tersely written as `SomeSmallString.str()` anyway, or more clearly written as `StringRef x = y;` rather than `StringRef x(y);` - so if you hit this in out-of-tree code, please update in one of those ways. Hopefully I've fixed everything in tree prior to this patch landing. --- diff --git a/llvm/include/llvm/ADT/SmallString.h b/llvm/include/llvm/ADT/SmallString.h index 56b0639..4f83a60 100644 --- a/llvm/include/llvm/ADT/SmallString.h +++ b/llvm/include/llvm/ADT/SmallString.h @@ -19,10 +19,22 @@ namespace llvm { +namespace impl { +template struct SmallStringConversionHelper1 { + operator StringRef() const { return static_cast(this)->str(); } +}; +struct SmallStringConversionHelper2 { + explicit operator StringRef() const = delete; +}; +} // namespace impl + /// SmallString - A SmallString is just a SmallVector with methods and accessors /// that make it work better as a string (e.g. operator+ etc). -template -class SmallString : public SmallVector { +template +class SmallString + : public SmallVector, + public impl::SmallStringConversionHelper1>, + public impl::SmallStringConversionHelper2 { public: /// Default ctor - Initialize to empty. SmallString() = default; @@ -266,7 +278,6 @@ public: } /// Implicit conversion to StringRef. - operator StringRef() const { return str(); } explicit operator std::string() const { return std::string(this->data(), this->size());