[all-commits] [llvm/llvm-project] 03282f: [clang] C++98 implicit moves are back with a venge...

Matheus Izvekov via All-commits all-commits at lists.llvm.org
Tue Jul 13 10:17:08 PDT 2021


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 03282f2fe14e9dd61aaeeda3785f56c7ccb4f3c9
      https://github.com/llvm/llvm-project/commit/03282f2fe14e9dd61aaeeda3785f56c7ccb4f3c9
  Author: Matheus Izvekov <mizvekov at gmail.com>
  Date:   2021-07-13 (Tue, 13 Jul 2021)

  Changed paths:
    M clang/lib/Sema/SemaStmt.cpp
    M clang/test/CXX/class/class.init/class.copy.elision/p3.cpp
    M clang/test/SemaCXX/conversion-function.cpp
    M clang/test/SemaObjCXX/block-capture.mm

  Log Message:
  -----------
  [clang] C++98 implicit moves are back with a vengeance

After taking C++98 implicit moves out in D104500,
we put it back in, but now in a new form which preserves
compatibility with pure C++98 programs, while at the same time
giving almost all the goodies from P1825.

* We use the exact same rules as C++20 with regards to which
  id-expressions are move eligible. The previous
  incarnation would only benefit from the proper subset which is
  copy ellidable. This means we can implicit move, in addition:
  * Parameters.
  * RValue references.
  * Exception variables.
  * Variables with higher-than-natural required alignment.
  * Objects with different type from the function return type.
* We preserve the two-overload resolution, with one small tweak to the
  first one: If we either pick a (possibly converting) constructor which
  does not take an rvalue reference, or a user conversion operator which
  is not ref-qualified, we abort into the second overload resolution.

This gives C++98 almost all the implicit move patterns which we had created test
cases for, while at the same time preserving the meaning of these
three patterns, which are found in pure C++98 programs:
* Classes with both const and non-const copy constructors, but no move
  constructors, continue to have their non-const copy constructor
  selected.
* We continue to reject as ambiguous the following pattern:
```
struct A { A(B &); };
struct B { operator A(); };
A foo(B x) { return x; }
```
* We continue to pick the copy constructor in the following pattern:
```
class AutoPtrRef { };
struct AutoPtr {
  AutoPtr(AutoPtr &);
  AutoPtr();

  AutoPtr(AutoPtrRef);
  operator AutoPtrRef();
};
AutoPtr test_auto_ptr() {
  AutoPtr p;
  return p;
}
```

Signed-off-by: Matheus Izvekov <mizvekov at gmail.com>

Reviewed By: Quuxplusone

Differential Revision: https://reviews.llvm.org/D105756




More information about the All-commits mailing list