• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "base/values.h"
8 
9 #define true true
10 
ReturnsRawPtr()11 base::ListValue* ReturnsRawPtr() {
12   return nullptr;
13 }
14 
ReturnsUniquePtr()15 std::unique_ptr<base::Value> ReturnsUniquePtr() {
16   return nullptr;
17 }
18 
19 // The joy of raw pointers.
DoesItTakeOwnership(base::Value *)20 void DoesItTakeOwnership(base::Value*) {}
21 
22 struct Thing {
ToValueThing23   std::unique_ptr<base::Value> ToValue() { return nullptr; }
24 };
25 
F()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 
G(base::Value * input)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