189a1d03eSRichard // RUN: %check_clang_tidy %s performance-unnecessary-value-param %t -- -- -fdelayed-template-parsing 289a1d03eSRichard 389a1d03eSRichard struct ExpensiveToCopyType { 489a1d03eSRichard const ExpensiveToCopyType & constReference() const { 589a1d03eSRichard return *this; 689a1d03eSRichard } 789a1d03eSRichard void nonConstMethod(); 889a1d03eSRichard virtual ~ExpensiveToCopyType(); 989a1d03eSRichard }; 1089a1d03eSRichard 1189a1d03eSRichard void mutate(ExpensiveToCopyType &); 1289a1d03eSRichard void mutate(ExpensiveToCopyType *); 1389a1d03eSRichard void useAsConstReference(const ExpensiveToCopyType &); 1489a1d03eSRichard void useByValue(ExpensiveToCopyType); 1589a1d03eSRichard 1689a1d03eSRichard // This class simulates std::pair<>. It is trivially copy constructible 1789a1d03eSRichard // and trivially destructible, but not trivially copy assignable. 1889a1d03eSRichard class SomewhatTrivial { 1989a1d03eSRichard public: 2089a1d03eSRichard SomewhatTrivial(); 2189a1d03eSRichard SomewhatTrivial(const SomewhatTrivial&) = default; 2289a1d03eSRichard ~SomewhatTrivial() = default; 2389a1d03eSRichard SomewhatTrivial& operator=(const SomewhatTrivial&); 2489a1d03eSRichard }; 2589a1d03eSRichard 2689a1d03eSRichard void positiveExpensiveConstValue(const ExpensiveToCopyType Obj); 2789a1d03eSRichard // CHECK-FIXES: void positiveExpensiveConstValue(const ExpensiveToCopyType& Obj); 2889a1d03eSRichard void positiveExpensiveConstValue(const ExpensiveToCopyType Obj) { 2989a1d03eSRichard // 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] 3089a1d03eSRichard // CHECK-FIXES: void positiveExpensiveConstValue(const ExpensiveToCopyType& Obj) { 3189a1d03eSRichard } 3289a1d03eSRichard 3389a1d03eSRichard void positiveExpensiveValue(ExpensiveToCopyType Obj); 3489a1d03eSRichard // CHECK-FIXES: void positiveExpensiveValue(const ExpensiveToCopyType& Obj); 3589a1d03eSRichard void positiveExpensiveValue(ExpensiveToCopyType Obj) { 3689a1d03eSRichard // 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] 3789a1d03eSRichard // CHECK-FIXES: void positiveExpensiveValue(const ExpensiveToCopyType& Obj) { 3889a1d03eSRichard Obj.constReference(); 3989a1d03eSRichard useAsConstReference(Obj); 4089a1d03eSRichard auto Copy = Obj; 4189a1d03eSRichard useByValue(Obj); 4289a1d03eSRichard } 4389a1d03eSRichard 4489a1d03eSRichard void positiveWithComment(const ExpensiveToCopyType /* important */ S); 4589a1d03eSRichard // CHECK-FIXES: void positiveWithComment(const ExpensiveToCopyType& /* important */ S); 4689a1d03eSRichard void positiveWithComment(const ExpensiveToCopyType /* important */ S) { 4789a1d03eSRichard // CHECK-MESSAGES: [[@LINE-1]]:68: warning: the const qualified 4889a1d03eSRichard // CHECK-FIXES: void positiveWithComment(const ExpensiveToCopyType& /* important */ S) { 4989a1d03eSRichard } 5089a1d03eSRichard 5189a1d03eSRichard void positiveUnnamedParam(const ExpensiveToCopyType) { 5289a1d03eSRichard // CHECK-MESSAGES: [[@LINE-1]]:52: warning: the const qualified parameter #1 5389a1d03eSRichard // CHECK-FIXES: void positiveUnnamedParam(const ExpensiveToCopyType&) { 5489a1d03eSRichard } 5589a1d03eSRichard 5689a1d03eSRichard void positiveAndNegative(const ExpensiveToCopyType ConstCopy, const ExpensiveToCopyType& ConstRef, ExpensiveToCopyType Copy); 5789a1d03eSRichard // CHECK-FIXES: void positiveAndNegative(const ExpensiveToCopyType& ConstCopy, const ExpensiveToCopyType& ConstRef, const ExpensiveToCopyType& Copy); 5889a1d03eSRichard void positiveAndNegative(const ExpensiveToCopyType ConstCopy, const ExpensiveToCopyType& ConstRef, ExpensiveToCopyType Copy) { 5989a1d03eSRichard // CHECK-MESSAGES: [[@LINE-1]]:52: warning: the const qualified parameter 'ConstCopy' 6089a1d03eSRichard // CHECK-MESSAGES: [[@LINE-2]]:120: warning: the parameter 'Copy' 6189a1d03eSRichard // CHECK-FIXES: void positiveAndNegative(const ExpensiveToCopyType& ConstCopy, const ExpensiveToCopyType& ConstRef, const ExpensiveToCopyType& Copy) { 6289a1d03eSRichard } 6389a1d03eSRichard 6489a1d03eSRichard struct PositiveConstValueConstructor { 6589a1d03eSRichard PositiveConstValueConstructor(const ExpensiveToCopyType ConstCopy) {} 6689a1d03eSRichard // CHECK-MESSAGES: [[@LINE-1]]:59: warning: the const qualified parameter 'ConstCopy' 6789a1d03eSRichard // CHECK-FIXES: PositiveConstValueConstructor(const ExpensiveToCopyType& ConstCopy) {} 6889a1d03eSRichard }; 6989a1d03eSRichard 7089a1d03eSRichard template <typename T> void templateWithNonTemplatizedParameter(const ExpensiveToCopyType S, T V) { 7189a1d03eSRichard // CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'S' 72*8e42e0d2SVitaly Goldshteyn // CHECK-MESSAGES: [[@LINE-2]]:95: warning: the parameter 'V' 73*8e42e0d2SVitaly Goldshteyn // CHECK-FIXES: template <typename T> void templateWithNonTemplatizedParameter(const ExpensiveToCopyType& S, const T& V) { 7489a1d03eSRichard } 7589a1d03eSRichard 7689a1d03eSRichard void instantiated() { 7789a1d03eSRichard templateWithNonTemplatizedParameter(ExpensiveToCopyType(), ExpensiveToCopyType()); 7889a1d03eSRichard templateWithNonTemplatizedParameter(ExpensiveToCopyType(), 5); 7989a1d03eSRichard } 8089a1d03eSRichard 8189a1d03eSRichard template <typename T> void negativeTemplateType(const T V) { 8289a1d03eSRichard } 8389a1d03eSRichard 8489a1d03eSRichard void negativeArray(const ExpensiveToCopyType[]) { 8589a1d03eSRichard } 8689a1d03eSRichard 8789a1d03eSRichard void negativePointer(ExpensiveToCopyType* Obj) { 8889a1d03eSRichard } 8989a1d03eSRichard 9089a1d03eSRichard void negativeConstPointer(const ExpensiveToCopyType* Obj) { 9189a1d03eSRichard } 9289a1d03eSRichard 9389a1d03eSRichard void negativeConstReference(const ExpensiveToCopyType& Obj) { 9489a1d03eSRichard } 9589a1d03eSRichard 9689a1d03eSRichard void negativeReference(ExpensiveToCopyType& Obj) { 9789a1d03eSRichard } 9889a1d03eSRichard 9989a1d03eSRichard void negativeUniversalReference(ExpensiveToCopyType&& Obj) { 10089a1d03eSRichard } 10189a1d03eSRichard 10289a1d03eSRichard void negativeSomewhatTrivialConstValue(const SomewhatTrivial Somewhat) { 10389a1d03eSRichard } 10489a1d03eSRichard 10589a1d03eSRichard void negativeSomewhatTrivialValue(SomewhatTrivial Somewhat) { 10689a1d03eSRichard } 10789a1d03eSRichard 10889a1d03eSRichard void negativeConstBuiltIn(const int I) { 10989a1d03eSRichard } 11089a1d03eSRichard 11189a1d03eSRichard void negativeValueBuiltIn(int I) { 11289a1d03eSRichard } 11389a1d03eSRichard 11489a1d03eSRichard void negativeValueIsMutatedByReference(ExpensiveToCopyType Obj) { 11589a1d03eSRichard mutate(Obj); 11689a1d03eSRichard } 11789a1d03eSRichard 11889a1d03eSRichard void negativeValueIsMutatatedByPointer(ExpensiveToCopyType Obj) { 11989a1d03eSRichard mutate(&Obj); 12089a1d03eSRichard } 12189a1d03eSRichard 12289a1d03eSRichard void negativeValueIsReassigned(ExpensiveToCopyType Obj) { 12389a1d03eSRichard Obj = ExpensiveToCopyType(); 12489a1d03eSRichard } 12589a1d03eSRichard 12689a1d03eSRichard void negativeValueNonConstMethodIsCalled(ExpensiveToCopyType Obj) { 12789a1d03eSRichard Obj.nonConstMethod(); 12889a1d03eSRichard } 12989a1d03eSRichard 13089a1d03eSRichard struct PositiveValueUnusedConstructor { 13189a1d03eSRichard PositiveValueUnusedConstructor(ExpensiveToCopyType Copy) {} 13289a1d03eSRichard // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'Copy' 13389a1d03eSRichard // CHECK-FIXES: PositiveValueUnusedConstructor(const ExpensiveToCopyType& Copy) {} 13489a1d03eSRichard }; 13589a1d03eSRichard 13689a1d03eSRichard struct PositiveValueCopiedConstructor { 13789a1d03eSRichard PositiveValueCopiedConstructor(ExpensiveToCopyType Copy) : Field(Copy) {} 13889a1d03eSRichard // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'Copy' 13989a1d03eSRichard // CHECK-FIXES: PositiveValueCopiedConstructor(const ExpensiveToCopyType& Copy) : Field(Copy) {} 14089a1d03eSRichard ExpensiveToCopyType Field; 14189a1d03eSRichard }; 14289a1d03eSRichard 14389a1d03eSRichard template <typename T> 14489a1d03eSRichard struct Container { 14589a1d03eSRichard typedef const T & const_reference; 14689a1d03eSRichard }; 14789a1d03eSRichard 14889a1d03eSRichard void NegativeTypedefParam(const Container<ExpensiveToCopyType>::const_reference Param) { 14989a1d03eSRichard } 15089a1d03eSRichard 15189a1d03eSRichard #define UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY() \ 15289a1d03eSRichard void inMacro(const ExpensiveToCopyType T) { \ 15389a1d03eSRichard } \ 15489a1d03eSRichard // Ensure fix is not applied. 15589a1d03eSRichard // CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) { 15689a1d03eSRichard 15789a1d03eSRichard UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY() 15889a1d03eSRichard // CHECK-MESSAGES: [[@LINE-1]]:1: warning: the const qualified parameter 'T' 15989a1d03eSRichard 16089a1d03eSRichard #define UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(ARGUMENT) \ 16189a1d03eSRichard ARGUMENT 16289a1d03eSRichard 16389a1d03eSRichard UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {}) 16489a1d03eSRichard // CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'InMacroArg' 16589a1d03eSRichard // CHECK-FIXES: void inMacroArgument(const ExpensiveToCopyType InMacroArg) {} 16689a1d03eSRichard 16789a1d03eSRichard struct VirtualMethod { 16889a1d03eSRichard virtual ~VirtualMethod() {} 16989a1d03eSRichard virtual void handle(ExpensiveToCopyType T) const = 0; 17089a1d03eSRichard }; 17189a1d03eSRichard 17289a1d03eSRichard struct NegativeOverriddenMethod : public VirtualMethod { 17389a1d03eSRichard void handle(ExpensiveToCopyType Overridden) const { 17489a1d03eSRichard // CHECK-FIXES: handle(ExpensiveToCopyType Overridden) const { 17589a1d03eSRichard } 17689a1d03eSRichard }; 17789a1d03eSRichard 17889a1d03eSRichard struct NegativeDeletedMethod { 17989a1d03eSRichard ~NegativeDeletedMethod() {} 18089a1d03eSRichard NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete; 18189a1d03eSRichard // CHECK-FIXES: NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete; 18289a1d03eSRichard }; 183