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