OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 struct A { | 5 struct A { |
6 A&& Pass(); | 6 A&& Pass(); |
7 }; | 7 }; |
8 | 8 |
9 struct B { | 9 struct B { |
10 B& Pass(); | 10 B& Pass(); |
11 }; | 11 }; |
12 | 12 |
13 struct C { | 13 struct C { |
14 A a; | 14 A a; |
15 }; | 15 }; |
16 | 16 |
17 struct D { | 17 struct D { |
18 D&& NotPass(); | 18 D&& NotPass(); |
19 }; | 19 }; |
20 | 20 |
21 struct E { | 21 struct E { |
22 E() : a(new A) {} | 22 E() : a(new A) {} |
23 ~E() { delete a; } | 23 ~E() { delete a; } |
24 A* a; | 24 A* a; |
25 }; | 25 }; |
26 | 26 |
27 void F() { | 27 struct F { |
| 28 explicit F(A&&); |
| 29 F&& Pass(); |
| 30 }; |
| 31 |
| 32 void Test() { |
| 33 // Pass that returns rvalue reference should use std::move. |
28 A a1; | 34 A a1; |
29 A a2 = std::move(a1); | 35 A a2 = std::move(a1); |
30 | 36 |
| 37 // Pass that doesn't return a rvalue reference should not be rewritten. |
31 B b1; | 38 B b1; |
32 B b2 = b1.Pass(); | 39 B b2 = b1.Pass(); |
33 | 40 |
| 41 // std::move() needs to wrap the entire expression when passing a member. |
34 C c; | 42 C c; |
35 A a3 = std::move(c.a); | 43 A a3 = std::move(c.a); |
36 | 44 |
| 45 // Don't rewrite things that return rvalue references that aren't named Pass. |
37 D d1; | 46 D d1; |
38 D d2 = d1.NotPass(); | 47 D d2 = d1.NotPass(); |
39 | 48 |
| 49 // Pass via a pointer type should dereference the pointer first. |
40 E e; | 50 E e; |
41 A a4 = std::move(*e.a); | 51 A a4 = std::move(*e.a); |
| 52 |
| 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)); |
42 } | 62 } |
OLD | NEW |