[PATCH] D105756: [clang] C++98 implicit moves are back with a vengeance

Matheus Izvekov via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sat Jul 10 14:40:06 PDT 2021


mizvekov created this revision.
mizvekov edited the summary of this revision.
mizvekov edited the summary of this revision.
mizvekov edited the summary of this revision.
mizvekov updated this revision to Diff 357688.
mizvekov added a comment.
mizvekov updated this revision to Diff 357692.
mizvekov updated this revision to Diff 357693.
mizvekov updated this revision to Diff 357748.
mizvekov edited the summary of this revision.
mizvekov added a reviewer: rsmith.
mizvekov added subscribers: Quuxplusone, jyknight, ldionne.
mizvekov published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

clang-tidy.


mizvekov added a comment.

.


mizvekov added a comment.

.


mizvekov added a comment.

.


After taking C++98 implicit moves out in D104500 <https://reviews.llvm.org/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 <https://reviews.llvm.org/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.
- 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 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 &) = delete; };
  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>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D105756

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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D105756.357748.patch
Type: text/x-patch
Size: 16702 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210710/6449b5fc/attachment-0001.bin>


More information about the cfe-commits mailing list