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 positiveWithComment(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-MESSAGES: [[@LINE-2]]:95: warning: the parameter 'V'
73   // CHECK-FIXES: template <typename T> void templateWithNonTemplatizedParameter(const ExpensiveToCopyType& S, const T& V) {
74 }
75 
76 void instantiated() {
77   templateWithNonTemplatizedParameter(ExpensiveToCopyType(), ExpensiveToCopyType());
78   templateWithNonTemplatizedParameter(ExpensiveToCopyType(), 5);
79 }
80 
81 template <typename T> void negativeTemplateType(const T V) {
82 }
83 
84 void negativeArray(const ExpensiveToCopyType[]) {
85 }
86 
87 void negativePointer(ExpensiveToCopyType* Obj) {
88 }
89 
90 void negativeConstPointer(const ExpensiveToCopyType* Obj) {
91 }
92 
93 void negativeConstReference(const ExpensiveToCopyType& Obj) {
94 }
95 
96 void negativeReference(ExpensiveToCopyType& Obj) {
97 }
98 
99 void negativeUniversalReference(ExpensiveToCopyType&& Obj) {
100 }
101 
102 void negativeSomewhatTrivialConstValue(const SomewhatTrivial Somewhat) {
103 }
104 
105 void negativeSomewhatTrivialValue(SomewhatTrivial Somewhat) {
106 }
107 
108 void negativeConstBuiltIn(const int I) {
109 }
110 
111 void negativeValueBuiltIn(int I) {
112 }
113 
114 void negativeValueIsMutatedByReference(ExpensiveToCopyType Obj) {
115   mutate(Obj);
116 }
117 
118 void negativeValueIsMutatatedByPointer(ExpensiveToCopyType Obj) {
119   mutate(&Obj);
120 }
121 
122 void negativeValueIsReassigned(ExpensiveToCopyType Obj) {
123   Obj = ExpensiveToCopyType();
124 }
125 
126 void negativeValueNonConstMethodIsCalled(ExpensiveToCopyType Obj) {
127   Obj.nonConstMethod();
128 }
129 
130 struct PositiveValueUnusedConstructor {
131   PositiveValueUnusedConstructor(ExpensiveToCopyType Copy) {}
132   // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'Copy'
133   // CHECK-FIXES: PositiveValueUnusedConstructor(const ExpensiveToCopyType& Copy) {}
134 };
135 
136 struct PositiveValueCopiedConstructor {
137   PositiveValueCopiedConstructor(ExpensiveToCopyType Copy) : Field(Copy) {}
138   // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'Copy'
139   // CHECK-FIXES: PositiveValueCopiedConstructor(const ExpensiveToCopyType& Copy) : Field(Copy) {}
140   ExpensiveToCopyType Field;
141 };
142 
143 template <typename T>
144 struct Container {
145   typedef const T & const_reference;
146 };
147 
148 void NegativeTypedefParam(const Container<ExpensiveToCopyType>::const_reference Param) {
149 }
150 
151 #define UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY()         \
152   void inMacro(const ExpensiveToCopyType T) {           \
153   }                                                     \
154 // Ensure fix is not applied.
155 // CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) {
156 
157 UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY()
158 // CHECK-MESSAGES: [[@LINE-1]]:1: warning: the const qualified parameter 'T'
159 
160 #define UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(ARGUMENT)     \
161   ARGUMENT
162 
163 UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {})
164 // CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'InMacroArg'
165 // CHECK-FIXES: void inMacroArgument(const ExpensiveToCopyType InMacroArg) {}
166 
167 struct VirtualMethod {
168   virtual ~VirtualMethod() {}
169   virtual void handle(ExpensiveToCopyType T) const = 0;
170 };
171 
172 struct NegativeOverriddenMethod : public VirtualMethod {
173   void handle(ExpensiveToCopyType Overridden) const {
174     // CHECK-FIXES: handle(ExpensiveToCopyType Overridden) const {
175   }
176 };
177 
178 struct NegativeDeletedMethod {
179   ~NegativeDeletedMethod() {}
180   NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete;
181   // CHECK-FIXES: NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete;
182 };
183