[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