1f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Copyright 2015 The Chromium Authors. All rights reserved. 2f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// found in the LICENSE file. 4f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct A { 6f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch A&& Pass(); 7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct B { 10f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch B& Pass(); 11f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 12f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct C { 14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch A a; 15f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 16f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 17f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct D { 18f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch D&& NotPass(); 19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 21f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct E { 22f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch E() : a(new A) {} 23f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ~E() { delete a; } 24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch A* a; 25f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 26f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 27f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct F { 28f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch explicit F(A&&); 29f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch F&& Pass(); 30f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 31f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 32f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid Test() { 33f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Pass that returns rvalue reference should use std::move. 34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch A a1; 35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch A a2 = a1.Pass(); 36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Pass that doesn't return a rvalue reference should not be rewritten. 38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch B b1; 39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch B b2 = b1.Pass(); 40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // std::move() needs to wrap the entire expression when passing a member. 42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch C c; 43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch A a3 = c.a.Pass(); 44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Don't rewrite things that return rvalue references that aren't named Pass. 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch D d1; 47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch D d2 = d1.NotPass(); 48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Pass via a pointer type should dereference the pointer first. 50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch E e; 51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch A a4 = e.a->Pass(); 52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Nested Pass() is handled correctly. 54f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch A a5; 55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch F f = F(a5.Pass()).Pass(); 56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Chained Pass is handled (mostly) correctly. The replacement applier dedupes 58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // the insertion of std::move, so the result is not completely correct... 59f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // ... but hopefully there's very little code following this broken pattern. 60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch A a6; 61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch A a7 = a6.Pass().Pass(); 62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 63