1 | // RUN: %check_clang_tidy %s performance-unnecessary-value-param %t -- -- -fdelayed-template-parsing |
2 | |
3 | struct ExpensiveToCopyType { |
4 | const ExpensiveToCopyType & constReference() const { |
5 | return *this; |
6 | } |
7 | void nonConstMethod(); |
8 | virtual ~ExpensiveToCopyType(); |
9 | }; |
10 | |
11 | void mutate(ExpensiveToCopyType &); |
12 | void mutate(ExpensiveToCopyType *); |
13 | void useAsConstReference(const ExpensiveToCopyType &); |
14 | void useByValue(ExpensiveToCopyType); |
15 | |
16 | // This class simulates std::pair<>. It is trivially copy constructible |
17 | // and trivially destructible, but not trivially copy assignable. |
18 | class SomewhatTrivial { |
19 | public: |
20 | SomewhatTrivial(); |
21 | SomewhatTrivial(const SomewhatTrivial&) = default; |
22 | ~SomewhatTrivial() = default; |
23 | SomewhatTrivial& operator=(const SomewhatTrivial&); |
24 | }; |
25 | |
26 | void positiveExpensiveConstValue(const ExpensiveToCopyType Obj); |
27 | // CHECK-FIXES: void positiveExpensiveConstValue(const ExpensiveToCopyType& Obj); |
28 | void positiveExpensiveConstValue(const ExpensiveToCopyType Obj) { |
29 | // CHECK-MESSAGES: [[@LINE-1]]:60: warning: the const qualified parameter 'Obj' is copied for each invocation; consider making it a reference [performance-unnecessary-value-param] |
30 | // CHECK-FIXES: void positiveExpensiveConstValue(const ExpensiveToCopyType& Obj) { |
31 | } |
32 | |
33 | void positiveExpensiveValue(ExpensiveToCopyType Obj); |
34 | // CHECK-FIXES: void positiveExpensiveValue(const ExpensiveToCopyType& Obj); |
35 | void positiveExpensiveValue(ExpensiveToCopyType Obj) { |
36 | // CHECK-MESSAGES: [[@LINE-1]]:49: warning: the parameter 'Obj' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param] |
37 | // CHECK-FIXES: void positiveExpensiveValue(const ExpensiveToCopyType& Obj) { |
38 | Obj.constReference(); |
39 | useAsConstReference(Obj); |
40 | auto Copy = Obj; |
41 | useByValue(Obj); |
42 | } |
43 | |
44 | void positiveWithComment(const ExpensiveToCopyType /* important */ S); |
45 | // CHECK-FIXES: void positiveWithComment(const ExpensiveToCopyType& /* important */ S); |
46 | void (const ExpensiveToCopyType /* important */ S) { |
47 | // CHECK-MESSAGES: [[@LINE-1]]:68: warning: the const qualified |
48 | // CHECK-FIXES: void positiveWithComment(const ExpensiveToCopyType& /* important */ S) { |
49 | } |
50 | |
51 | void positiveUnnamedParam(const ExpensiveToCopyType) { |
52 | // CHECK-MESSAGES: [[@LINE-1]]:52: warning: the const qualified parameter #1 |
53 | // CHECK-FIXES: void positiveUnnamedParam(const ExpensiveToCopyType&) { |
54 | } |
55 | |
56 | void positiveAndNegative(const ExpensiveToCopyType ConstCopy, const ExpensiveToCopyType& ConstRef, ExpensiveToCopyType Copy); |
57 | // CHECK-FIXES: void positiveAndNegative(const ExpensiveToCopyType& ConstCopy, const ExpensiveToCopyType& ConstRef, const ExpensiveToCopyType& Copy); |
58 | void positiveAndNegative(const ExpensiveToCopyType ConstCopy, const ExpensiveToCopyType& ConstRef, ExpensiveToCopyType Copy) { |
59 | // CHECK-MESSAGES: [[@LINE-1]]:52: warning: the const qualified parameter 'ConstCopy' |
60 | // CHECK-MESSAGES: [[@LINE-2]]:120: warning: the parameter 'Copy' |
61 | // CHECK-FIXES: void positiveAndNegative(const ExpensiveToCopyType& ConstCopy, const ExpensiveToCopyType& ConstRef, const ExpensiveToCopyType& Copy) { |
62 | } |
63 | |
64 | struct PositiveConstValueConstructor { |
65 | PositiveConstValueConstructor(const ExpensiveToCopyType ConstCopy) {} |
66 | // CHECK-MESSAGES: [[@LINE-1]]:59: warning: the const qualified parameter 'ConstCopy' |
67 | // CHECK-FIXES: PositiveConstValueConstructor(const ExpensiveToCopyType& ConstCopy) {} |
68 | }; |
69 | |
70 | template <typename T> void templateWithNonTemplatizedParameter(const ExpensiveToCopyType S, T V) { |
71 | // CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'S' |
72 | // CHECK-FIXES-NOT: template <typename T> void templateWithNonTemplatizedParameter(const ExpensiveToCopyType& S, T V) { |
73 | } |
74 | |
75 | void instantiated() { |
76 | templateWithNonTemplatizedParameter(S: ExpensiveToCopyType(), V: ExpensiveToCopyType()); |
77 | templateWithNonTemplatizedParameter(S: ExpensiveToCopyType(), V: 5); |
78 | } |
79 | |
80 | template <typename T> void negativeTemplateType(const T V) { |
81 | } |
82 | |
83 | void negativeArray(const ExpensiveToCopyType[]) { |
84 | } |
85 | |
86 | void negativePointer(ExpensiveToCopyType* Obj) { |
87 | } |
88 | |
89 | void negativeConstPointer(const ExpensiveToCopyType* Obj) { |
90 | } |
91 | |
92 | void negativeConstReference(const ExpensiveToCopyType& Obj) { |
93 | } |
94 | |
95 | void negativeReference(ExpensiveToCopyType& Obj) { |
96 | } |
97 | |
98 | void negativeUniversalReference(ExpensiveToCopyType&& Obj) { |
99 | } |
100 | |
101 | void negativeSomewhatTrivialConstValue(const SomewhatTrivial Somewhat) { |
102 | } |
103 | |
104 | void negativeSomewhatTrivialValue(SomewhatTrivial Somewhat) { |
105 | } |
106 | |
107 | void negativeConstBuiltIn(const int I) { |
108 | } |
109 | |
110 | void negativeValueBuiltIn(int I) { |
111 | } |
112 | |
113 | void negativeValueIsMutatedByReference(ExpensiveToCopyType Obj) { |
114 | mutate(Obj); |
115 | } |
116 | |
117 | void negativeValueIsMutatatedByPointer(ExpensiveToCopyType Obj) { |
118 | mutate(&Obj); |
119 | } |
120 | |
121 | void negativeValueIsReassigned(ExpensiveToCopyType Obj) { |
122 | Obj = ExpensiveToCopyType(); |
123 | } |
124 | |
125 | void negativeValueNonConstMethodIsCalled(ExpensiveToCopyType Obj) { |
126 | Obj.nonConstMethod(); |
127 | } |
128 | |
129 | struct PositiveValueUnusedConstructor { |
130 | PositiveValueUnusedConstructor(ExpensiveToCopyType Copy) {} |
131 | // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'Copy' |
132 | // CHECK-FIXES: PositiveValueUnusedConstructor(const ExpensiveToCopyType& Copy) {} |
133 | }; |
134 | |
135 | struct PositiveValueCopiedConstructor { |
136 | PositiveValueCopiedConstructor(ExpensiveToCopyType Copy) : Field(Copy) {} |
137 | // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'Copy' |
138 | // CHECK-FIXES: PositiveValueCopiedConstructor(const ExpensiveToCopyType& Copy) : Field(Copy) {} |
139 | ExpensiveToCopyType Field; |
140 | }; |
141 | |
142 | template <typename T> |
143 | struct Container { |
144 | typedef const T & const_reference; |
145 | }; |
146 | |
147 | void NegativeTypedefParam(const Container<ExpensiveToCopyType>::const_reference Param) { |
148 | } |
149 | |
150 | #define UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY() \ |
151 | void inMacro(const ExpensiveToCopyType T) { \ |
152 | } \ |
153 | // Ensure fix is not applied. |
154 | // CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) { |
155 | |
156 | UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY() |
157 | // CHECK-MESSAGES: [[@LINE-1]]:1: warning: the const qualified parameter 'T' |
158 | |
159 | #define UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(ARGUMENT) \ |
160 | ARGUMENT |
161 | |
162 | UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {}) |
163 | // CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'InMacroArg' |
164 | // CHECK-FIXES: void inMacroArgument(const ExpensiveToCopyType InMacroArg) {} |
165 | |
166 | struct VirtualMethod { |
167 | virtual ~VirtualMethod() {} |
168 | virtual void handle(ExpensiveToCopyType T) const = 0; |
169 | }; |
170 | |
171 | struct NegativeOverriddenMethod : public VirtualMethod { |
172 | void handle(ExpensiveToCopyType Overridden) const { |
173 | // CHECK-FIXES: handle(ExpensiveToCopyType Overridden) const { |
174 | } |
175 | }; |
176 | |
177 | struct NegativeDeletedMethod { |
178 | ~NegativeDeletedMethod() {} |
179 | NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete; |
180 | // CHECK-FIXES: NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete; |
181 | }; |
182 | |