1 // Copyright 2016 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 #include <memory> 6 7 #include "values.h" 8 9 #define true true 10 11 base::ListValue* ReturnsRawPtr() { 12 return nullptr; 13 } 14 15 std::unique_ptr<base::Value> ReturnsUniquePtr() { 16 return nullptr; 17 } 18 19 // The joy of raw pointers. 20 void DoesItTakeOwnership(base::Value*) {} 21 22 struct Thing { 23 std::unique_ptr<base::Value> ToValue() { return nullptr; } 24 }; 25 26 void F() { 27 base::ListValue list; 28 list.AppendBoolean(1 == 0); 29 list.AppendBoolean(true); 30 list.AppendInteger(static_cast<unsigned char>(1.0)); 31 list.AppendDouble(double{3}); 32 list.AppendString("abc"); 33 34 list.Append(ReturnsUniquePtr()); 35 Thing thing; 36 list.Append(thing.ToValue()); 37 std::unique_ptr<base::Value> unique_ptr_var; 38 list.Append(std::move(unique_ptr_var)); 39 } 40 41 void G(base::Value* input) { 42 base::ListValue list; 43 44 std::unique_ptr<base::ListValue> local(new base::ListValue()); 45 // Not rewritten, since it often makes more sense to change the function 46 // prototype. 47 local->Append(input); 48 // Should be rewritten: it will only be moved after it's no longer referenced. 49 list.Append(std::move(local)); 50 51 // Not rewritten, since it would be used after it's moved. In theory, we could 52 // automatically handle this too, but the risk of accidentally breaking 53 // something is much higher. 54 base::ListValue* clever_list = new base::ListValue; 55 list.Append(clever_list); 56 clever_list->AppendInteger(2); 57 58 // Not rewritten, since it often makes more sense to change the function 59 // prototype. 60 base::Value* returned_value = ReturnsRawPtr(); 61 list.Append(returned_value); 62 63 // Should be rewritten. The reassignment should be transformed into 64 // .reset(). 65 std::unique_ptr<base::ListValue> reused_list(new base::ListValue); 66 reused_list->AppendInteger(1); 67 list.Append(std::move(reused_list)); 68 reused_list.reset(new base::ListValue); 69 reused_list->AppendInteger(3); 70 list.Append(std::move(reused_list)); 71 72 // This shouldn't be rewritten, since the reassignment is the return 73 // value of a function. 74 base::ListValue* reused_list_2 = new base::ListValue; 75 reused_list_2->AppendInteger(4); 76 list.Append(reused_list_2); 77 reused_list_2 = ReturnsRawPtr(); 78 reused_list_2->AppendInteger(5); 79 list.Append(reused_list_2); 80 81 // auto should be expanded to a std::unique_ptr containing the deduced type. 82 std::unique_ptr<class base::ListValue> auto_list(new base::ListValue); 83 auto_list->AppendInteger(6); 84 list.Append(std::move(auto_list)); 85 86 std::unique_ptr<class base::ListValue> auto_list_2(new base::ListValue); 87 auto_list_2->AppendInteger(7); 88 list.Append(std::move(auto_list_2)); 89 90 // Shouldn't be rewritten: a raw pointer is passed to a function which may or 91 // may not take ownership. 92 base::ListValue* maybe_owned_list = new base::ListValue; 93 DoesItTakeOwnership(maybe_owned_list); 94 list.Append(maybe_owned_list); 95 96 // Should be rewritten, even though it doesn't have an initializer. 97 std::unique_ptr<base::ListValue> list_with_no_initializer; 98 list_with_no_initializer.reset(new base::ListValue); 99 list.Append(std::move(list_with_no_initializer)); 100 101 // Make sure C++98 style initialization is correctly handled. 102 std::unique_ptr<base::ListValue> cxx98_list(new base::ListValue); 103 list.Append(std::move(cxx98_list)); 104 105 // C++11 style syntax currently causes the tool to bail out: this is banned in 106 // Chromium style anyway. 107 base::ListValue* cxx11_list{new base::ListValue}; 108 list.Append(cxx11_list); 109 } 110