| 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 |