blob: 65003f88120db3c70788b84ab511d8ce05f3c85b [file] [log] [blame]
Daniel Cheng2d0222002015-12-05 04:45:281// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5struct A {
6 A&& Pass();
7};
8
9struct B {
10 B& Pass();
11};
12
13struct C {
14 A a;
15};
16
17struct D {
18 D&& NotPass();
19};
20
dchengfc0d8222015-12-17 03:10:5221struct E {
22 E() : a(new A) {}
23 ~E() { delete a; }
24 A* a;
25};
26
dcheng47428582015-12-17 22:19:4127struct F {
28 explicit F(A&&);
29 F&& Pass();
30};
31
32void Test() {
33 // Pass that returns rvalue reference should use std::move.
Daniel Cheng2d0222002015-12-05 04:45:2834 A a1;
35 A a2 = std::move(a1);
36
dcheng47428582015-12-17 22:19:4137 // Pass that doesn't return a rvalue reference should not be rewritten.
Daniel Cheng2d0222002015-12-05 04:45:2838 B b1;
dchengfc0d8222015-12-17 03:10:5239 B b2 = b1.Pass();
Daniel Cheng2d0222002015-12-05 04:45:2840
dcheng47428582015-12-17 22:19:4141 // std::move() needs to wrap the entire expression when passing a member.
Daniel Cheng2d0222002015-12-05 04:45:2842 C c;
43 A a3 = std::move(c.a);
44
dcheng47428582015-12-17 22:19:4145 // Don't rewrite things that return rvalue references that aren't named Pass.
Daniel Cheng2d0222002015-12-05 04:45:2846 D d1;
47 D d2 = d1.NotPass();
dchengfc0d8222015-12-17 03:10:5248
dcheng47428582015-12-17 22:19:4149 // Pass via a pointer type should dereference the pointer first.
dchengfc0d8222015-12-17 03:10:5250 E e;
51 A a4 = std::move(*e.a);
dcheng47428582015-12-17 22:19:4152
53 // Nested Pass() is handled correctly.
54 A a5;
55 F f = std::move(F(std::move(a5)));
56
57 // Chained Pass is handled (mostly) correctly. The replacement applier dedupes
58 // the insertion of std::move, so the result is not completely correct...
59 // ... but hopefully there's very little code following this broken pattern.
60 A a6;
61 A a7 = std::move(a6));
Daniel Cheng2d0222002015-12-05 04:45:2862}