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 3 // found in the LICENSE file. 4 5 struct A { 6 A&& Pass(); 7 }; 8 9 struct B { 10 B& Pass(); 11 }; 12 13 struct C { 14 A a; 15 }; 16 17 struct D { 18 D&& NotPass(); 19 }; 20 21 struct E { 22 E() : a(new A) {} 23 ~E() { delete a; } 24 A* a; 25 }; 26 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. 34 A a1; 35 A a2 = std::move(a1); 36 37 // Pass that doesn't return a rvalue reference should not be rewritten. 38 B b1; 39 B b2 = b1.Pass(); 40 41 // std::move() needs to wrap the entire expression when passing a member. 42 C c; 43 A a3 = std::move(c.a); 44 45 // Don't rewrite things that return rvalue references that aren't named Pass. 46 D d1; 47 D d2 = d1.NotPass(); 48 49 // Pass via a pointer type should dereference the pointer first. 50 E e; 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)); 62 } 63