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 = a1.Pass();
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 = c.a.Pass();
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 = e.a->Pass();
52 
53   // Nested Pass() is handled correctly.
54   A a5;
55   F f = F(a5.Pass()).Pass();
56 
57   // Chained Pass is handled correctly.
58   A a6;
59   A a7 = a6.Pass().Pass();
60 }
61