[llvm] e2d3084 - PR51018: Disallow explicit construction of StringRef from SmallString due to ambiguity in C++23
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 8 13:38:43 PDT 2021
Author: David Blaikie
Date: 2021-07-08T13:37:57-07:00
New Revision: e2d30846327c7ec5cc9d2a46aa9bcd9c2c4eff93
URL: https://github.com/llvm/llvm-project/commit/e2d30846327c7ec5cc9d2a46aa9bcd9c2c4eff93
DIFF: https://github.com/llvm/llvm-project/commit/e2d30846327c7ec5cc9d2a46aa9bcd9c2c4eff93.diff
LOG: 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.
Added:
Modified:
llvm/include/llvm/ADT/SmallString.h
Removed:
################################################################################
diff --git a/llvm/include/llvm/ADT/SmallString.h b/llvm/include/llvm/ADT/SmallString.h
index 56b0639b98cc..4f83a60aefe6 100644
--- a/llvm/include/llvm/ADT/SmallString.h
+++ b/llvm/include/llvm/ADT/SmallString.h
@@ -19,10 +19,22 @@
namespace llvm {
+namespace impl {
+template <typename T> struct SmallStringConversionHelper1 {
+ operator StringRef() const { return static_cast<const T *>(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<unsigned InternalLen>
-class SmallString : public SmallVector<char, InternalLen> {
+template <unsigned InternalLen>
+class SmallString
+ : public SmallVector<char, InternalLen>,
+ public impl::SmallStringConversionHelper1<SmallString<InternalLen>>,
+ public impl::SmallStringConversionHelper2 {
public:
/// Default ctor - Initialize to empty.
SmallString() = default;
@@ -266,7 +278,6 @@ class SmallString : public SmallVector<char, InternalLen> {
}
/// Implicit conversion to StringRef.
- operator StringRef() const { return str(); }
explicit operator std::string() const {
return std::string(this->data(), this->size());
More information about the llvm-commits
mailing list