[PATCH] D99005: [clang] Implement P2266 Simpler implicit move
Stephan Bergmann via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 17 01:28:40 PDT 2021
sberg added a comment.
For the record, the one other breakage of a LibreOffice build with this is the handful of places that needed https://git.libreoffice.org/core/+/433ab39b2175bdadb4916373cd2dc8e1aabc08a5%5E%21 "Adapt implicit OString return value construction to C++23 P2266R1": In a nutshell, LO has an `OString` class with (non-explicit) constructors from any kind of `char` pointer or array, where the "array of `N` `const char`" variant (no. 3 below) is special, as it determines the string length as `N - 1` (whereas all the other variants search for the terminating NUL to determine the length). That requires another constructor overload (no. 2 below) for non-`const` arrays, taking a non-`const` lvalue reference, which now causes issues when that constructor shall implicitly be used in `return` statements:
$ cat test.cc
#include <cstddef>
template<typename> struct CharPtrDetector {};
template<> struct CharPtrDetector<char *>
{ using type = int; };
template<> struct CharPtrDetector<char const *>
{ using type = int; };
template<typename> struct NonConstCharArrayDetector {};
template<std::size_t N> struct NonConstCharArrayDetector<char [N]>
{ using type = int; };
template<typename> struct ConstCharArrayDetector {};
template<std::size_t N> struct ConstCharArrayDetector<char const [N]>
{ using type = int; };
struct OString {
template<typename T>
OString(T const &, typename CharPtrDetector<T>::type = 0); // #1
template<typename T>
OString(T &, typename NonConstCharArrayDetector<T>::type = 0); // #2
template<typename T>
OString(T &, typename ConstCharArrayDetector<T>::type = 0); // #3
};
OString good1a() {
char * p;
//...
return p; // use #1
};
OString good1b() {
char const * p;
//...
return p; // use #1
};
OString bad2() {
char buf[10];
//...
return buf; // use #2
}
OString good3() {
return "foo"; // use #3
}
$ clang++ -std=c++20 -fsyntax-only test.cc
$ clang++ -std=c++2b -fsyntax-only test.cc
test.cc:41:12: error: no viable conversion from returned value of type 'char [10]' to function return type 'OString'
return buf; // use #2
^~~
test.cc:17:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'char [10]' to 'const OString &' for 1st argument
struct OString {
^
test.cc:17:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'char [10]' to 'OString &&' for 1st argument
struct OString {
^
test.cc:21:5: note: candidate constructor [with T = char [10]] not viable: expects an lvalue for 1st argument
OString(T &, typename NonConstCharArrayDetector<T>::type = 0); // #2
^
test.cc:19:5: note: candidate template ignored: substitution failure [with T = char [10]]: no type named 'type' in 'CharPtrDetector<char [10]>'
OString(T const &, typename CharPtrDetector<T>::type = 0); // #1
^ ~~~~
test.cc:23:5: note: candidate template ignored: substitution failure [with T = char [10]]: no type named 'type' in 'ConstCharArrayDetector<char [10]>'
OString(T &, typename ConstCharArrayDetector<T>::type = 0); // #3
^ ~~~~
1 error generated.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D99005/new/
https://reviews.llvm.org/D99005
More information about the cfe-commits
mailing list