brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.2 KiB · 8dc13d3 Raw
390 lines · cpp
1// RUN: %check_clang_tidy %s performance-unnecessary-value-param %t -- -- -fno-delayed-template-parsing2 3// CHECK-FIXES: #include <utility>4 5namespace std {6template <typename>7struct remove_reference;8 9template <typename _Tp>10struct remove_reference {11  typedef _Tp type;12};13 14template <typename _Tp>15struct remove_reference<_Tp &> {16  typedef _Tp type;17};18 19template <typename _Tp>20struct remove_reference<_Tp &&> {21  typedef _Tp type;22};23 24template <typename _Tp>25constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) {26  return static_cast<typename std::remove_reference<_Tp>::type &&>(__t);27}28} // namespace std29 30struct ExpensiveToCopyType {31  const ExpensiveToCopyType & constReference() const {32    return *this;33  }34  void nonConstMethod();35  virtual ~ExpensiveToCopyType();36};37 38void mutate(ExpensiveToCopyType &);39void mutate(ExpensiveToCopyType *);40void useAsConstReference(const ExpensiveToCopyType &);41void useByValue(ExpensiveToCopyType);42 43template <class T> class Vector {44 public:45  using iterator = T*;46  using const_iterator = const T*;47 48  Vector(const Vector&);49  Vector& operator=(const Vector&);50 51  iterator begin();52  iterator end();53  const_iterator begin() const;54  const_iterator end() const;55};56 57// This class simulates std::pair<>. It is trivially copy constructible58// and trivially destructible, but not trivially copy assignable.59class SomewhatTrivial {60 public:61  SomewhatTrivial();62  SomewhatTrivial(const SomewhatTrivial&) = default;63  ~SomewhatTrivial() = default;64  SomewhatTrivial& operator=(const SomewhatTrivial&);65};66 67struct MoveOnlyType {68  MoveOnlyType(const MoveOnlyType &) = delete;69  MoveOnlyType(MoveOnlyType &&) = default;70  ~MoveOnlyType();71  void constMethod() const;72};73 74struct ExpensiveMovableType {75  ExpensiveMovableType();76  ExpensiveMovableType(ExpensiveMovableType &&);77  ExpensiveMovableType(const ExpensiveMovableType &) = default;78  ExpensiveMovableType &operator=(const ExpensiveMovableType &) = default;79  ExpensiveMovableType &operator=(ExpensiveMovableType &&);80  ~ExpensiveMovableType();81};82 83void positiveExpensiveConstValue(const ExpensiveToCopyType Obj);84// CHECK-FIXES: void positiveExpensiveConstValue(const ExpensiveToCopyType& Obj);85void positiveExpensiveConstValue(const ExpensiveToCopyType Obj) {86  // CHECK-MESSAGES: [[@LINE-1]]:60: warning: the const qualified parameter 'Obj' of type 'const ExpensiveToCopyType' is copied for each invocation; consider making it a reference [performance-unnecessary-value-param]87  // CHECK-FIXES: void positiveExpensiveConstValue(const ExpensiveToCopyType& Obj) {88}89 90void positiveExpensiveValue(ExpensiveToCopyType Obj);91// CHECK-FIXES: void positiveExpensiveValue(const ExpensiveToCopyType& Obj);92void positiveExpensiveValue(ExpensiveToCopyType Obj) {93  // CHECK-MESSAGES: [[@LINE-1]]:49: warning: the parameter 'Obj' of type 'ExpensiveToCopyType'  is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param]94  // CHECK-FIXES: void positiveExpensiveValue(const ExpensiveToCopyType& Obj) {95  Obj.constReference();96  useAsConstReference(Obj);97  auto Copy = Obj;98  useByValue(Obj);99}100 101void positiveVector(Vector<ExpensiveToCopyType> V) {102  // CHECK-MESSAGES: [[@LINE-1]]:49: warning: the parameter 'V' of type 'Vector<ExpensiveToCopyType>' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param]103  // CHECK-FIXES: void positiveVector(const Vector<ExpensiveToCopyType>& V) {104  for (const auto& Obj : V) {105    useByValue(Obj);106  }107}108 109void positiveWithComment(const ExpensiveToCopyType /* important */ S);110// CHECK-FIXES: void positiveWithComment(const ExpensiveToCopyType& /* important */ S);111void positiveWithComment(const ExpensiveToCopyType /* important */ S) {112  // CHECK-MESSAGES: [[@LINE-1]]:68: warning: the const qualified113  // CHECK-FIXES: void positiveWithComment(const ExpensiveToCopyType& /* important */ S) {114}115 116void positiveUnnamedParam(const ExpensiveToCopyType) {117  // CHECK-MESSAGES: [[@LINE-1]]:52: warning: the const qualified parameter #1118  // CHECK-FIXES: void positiveUnnamedParam(const ExpensiveToCopyType&) {119}120 121void positiveAndNegative(const ExpensiveToCopyType ConstCopy, const ExpensiveToCopyType& ConstRef, ExpensiveToCopyType Copy);122// CHECK-FIXES: void positiveAndNegative(const ExpensiveToCopyType& ConstCopy, const ExpensiveToCopyType& ConstRef, const ExpensiveToCopyType& Copy);123void positiveAndNegative(const ExpensiveToCopyType ConstCopy, const ExpensiveToCopyType& ConstRef, ExpensiveToCopyType Copy) {124  // CHECK-MESSAGES: [[@LINE-1]]:52: warning: the const qualified parameter 'ConstCopy'125  // CHECK-MESSAGES: [[@LINE-2]]:120: warning: the parameter 'Copy'126  // CHECK-FIXES: void positiveAndNegative(const ExpensiveToCopyType& ConstCopy, const ExpensiveToCopyType& ConstRef, const ExpensiveToCopyType& Copy) {127}128 129struct PositiveConstValueConstructor {130  PositiveConstValueConstructor(const ExpensiveToCopyType ConstCopy) {}131  // CHECK-MESSAGES: [[@LINE-1]]:59: warning: the const qualified parameter 'ConstCopy'132  // CHECK-FIXES: PositiveConstValueConstructor(const ExpensiveToCopyType& ConstCopy) {}133};134 135void negativeArray(const ExpensiveToCopyType[]) {136}137 138void negativePointer(ExpensiveToCopyType* Obj) {139}140 141void negativeConstPointer(const ExpensiveToCopyType* Obj) {142}143 144void negativeConstReference(const ExpensiveToCopyType& Obj) {145}146 147void negativeReference(ExpensiveToCopyType& Obj) {148}149 150void negativeUniversalReference(ExpensiveToCopyType&& Obj) {151}152 153void negativeSomewhatTrivialConstValue(const SomewhatTrivial Somewhat) {154}155 156void negativeSomewhatTrivialValue(SomewhatTrivial Somewhat) {157}158 159void negativeConstBuiltIn(const int I) {160}161 162void negativeValueBuiltIn(int I) {163}164 165void negativeValueIsMutatedByReference(ExpensiveToCopyType Obj) {166  mutate(Obj);167}168 169void negativeValueIsMutatatedByPointer(ExpensiveToCopyType Obj) {170  mutate(&Obj);171}172 173void negativeValueIsReassigned(ExpensiveToCopyType Obj) {174  Obj = ExpensiveToCopyType();175}176 177void negativeValueNonConstMethodIsCalled(ExpensiveToCopyType Obj) {178  Obj.nonConstMethod();179}180 181struct PositiveValueUnusedConstructor {182  PositiveValueUnusedConstructor(ExpensiveToCopyType Copy) {}183  // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'Copy'184  // CHECK-FIXES: PositiveValueUnusedConstructor(const ExpensiveToCopyType& Copy) {}185};186 187struct PositiveValueCopiedConstructor {188  PositiveValueCopiedConstructor(ExpensiveToCopyType Copy) : Field(Copy) {}189  // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'Copy'190  // CHECK-FIXES: PositiveValueCopiedConstructor(const ExpensiveToCopyType& Copy) : Field(Copy) {}191  ExpensiveToCopyType Field;192};193 194struct PositiveValueMovableConstructor {195  PositiveValueMovableConstructor(ExpensiveMovableType Copy) : Field(Copy) {}196  // CHECK-MESSAGES: [[@LINE-1]]:70: warning: parameter 'Copy'197  // CHECK-FIXES: PositiveValueMovableConstructor(ExpensiveMovableType Copy) : Field(std::move(Copy)) {}198  ExpensiveMovableType Field;199};200 201struct NegativeValueMovedConstructor {202  NegativeValueMovedConstructor(ExpensiveMovableType Copy) : Field(static_cast<ExpensiveMovableType &&>(Copy)) {}203  ExpensiveMovableType Field;204};205 206template <typename T>207struct Container {208  typedef const T & const_reference;209};210 211void NegativeTypedefParam(const Container<ExpensiveToCopyType>::const_reference Param) {212}213 214#define UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY()         \215  void inMacro(const ExpensiveToCopyType T) {           \216  }                                                     \217// Ensure fix is not applied.218// CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) { {{\\}}219 220UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY()221// CHECK-MESSAGES: [[@LINE-1]]:1: warning: the const qualified parameter 'T'222 223#define UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(ARGUMENT)     \224  ARGUMENT225 226UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {})227// CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'InMacroArg'228// CHECK-FIXES: UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {})229 230struct VirtualMethod {231  virtual ~VirtualMethod() {}232  virtual void handle(ExpensiveToCopyType T) const = 0;233};234 235struct NegativeOverriddenMethod : public VirtualMethod {236  void handle(ExpensiveToCopyType Overridden) const {237    // CHECK-FIXES: void handle(ExpensiveToCopyType Overridden) const {238  }239};240 241struct VirtualMethodWarningOnly {242  virtual void methodWithExpensiveValueParam(ExpensiveToCopyType T) {}243  // CHECK-MESSAGES: [[@LINE-1]]:66: warning: the parameter 'T' of type 'ExpensiveToCopyType' is copied244  // CHECK-FIXES: virtual void methodWithExpensiveValueParam(ExpensiveToCopyType T) {}245  virtual ~VirtualMethodWarningOnly() {}246};247 248struct PositiveNonVirualMethod {249  void method(const ExpensiveToCopyType T) {}250  // CHECK-MESSAGES: [[@LINE-1]]:41: warning: the const qualified parameter 'T' of type 'const ExpensiveToCopyType' is copied251  // CHECK-FIXES: void method(const ExpensiveToCopyType& T) {}252};253 254struct NegativeDeletedMethod {255  ~NegativeDeletedMethod() {}256  NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete;257  // CHECK-FIXES: NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete;258};259 260void NegativeMoveOnlyTypePassedByValue(MoveOnlyType M) {261  M.constMethod();262}263 264void PositiveMoveOnCopyConstruction(ExpensiveMovableType E) {265  auto F = E;266  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: parameter 'E' of type 'ExpensiveMovableType' is passed by value and only copied once; consider moving it to avoid unnecessary copies [performance-unnecessary-value-param]267  // CHECK-FIXES: auto F = std::move(E);268}269 270void PositiveConstRefNotMoveSinceReferencedMultipleTimes(ExpensiveMovableType E) {271  // CHECK-MESSAGES: [[@LINE-1]]:79: warning: the parameter 'E' of type 'ExpensiveMovableType' is copied272  // CHECK-FIXES: void PositiveConstRefNotMoveSinceReferencedMultipleTimes(const ExpensiveMovableType& E) {273  auto F = E;274  auto G = E;275}276 277void PositiveMoveOnCopyAssignment(ExpensiveMovableType E) {278  ExpensiveMovableType F;279  F = E;280  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: parameter 'E' of type 'ExpensiveMovableType' is passed by value281  // CHECK-FIXES: F = std::move(E);282}283 284struct NotCopyAssigned {285  NotCopyAssigned &operator=(const ExpensiveMovableType &);286};287 288void PositiveNoMoveForNonCopyAssignmentOperator(ExpensiveMovableType E) {289  // CHECK-MESSAGES: [[@LINE-1]]:70: warning: the parameter 'E' of type 'ExpensiveMovableType' is copied290  // CHECK-FIXES: void PositiveNoMoveForNonCopyAssignmentOperator(const ExpensiveMovableType& E) {291  NotCopyAssigned N;292  N = E;293}294 295// The argument could be moved but is not since copy statement is inside a loop.296void PositiveNoMoveInsideLoop(ExpensiveMovableType E) {297  // CHECK-MESSAGES: [[@LINE-1]]:52: warning: the parameter 'E' of type 'ExpensiveMovableType' is copied298  // CHECK-FIXES: void PositiveNoMoveInsideLoop(const ExpensiveMovableType& E) {299  for (;;) {300    auto F = E;301  }302}303 304void PositiveConstRefNotMoveConstructible(ExpensiveToCopyType T) {305  // CHECK-MESSAGES: [[@LINE-1]]:63: warning: the parameter 'T' of type 'ExpensiveToCopyType' is copied306  // CHECK-FIXES: void PositiveConstRefNotMoveConstructible(const ExpensiveToCopyType& T) {307  auto U = T;308}309 310void PositiveConstRefNotMoveAssignable(ExpensiveToCopyType A) {311  // CHECK-MESSAGES: [[@LINE-1]]:60: warning: the parameter 'A' of type 'ExpensiveToCopyType' is copied312  // CHECK-FIXES: void PositiveConstRefNotMoveAssignable(const ExpensiveToCopyType& A) {313  ExpensiveToCopyType B;314  B = A;315}316 317// Case where parameter in declaration is already const-qualified but not in318// implementation. Make sure a second 'const' is not added to the declaration.319void PositiveConstDeclaration(const ExpensiveToCopyType A);320// CHECK-FIXES: void PositiveConstDeclaration(const ExpensiveToCopyType& A);321void PositiveConstDeclaration(ExpensiveToCopyType A) {322  // CHECK-MESSAGES: [[@LINE-1]]:51: warning: the parameter 'A' of type 'ExpensiveToCopyType' is copied323  // CHECK-FIXES: void PositiveConstDeclaration(const ExpensiveToCopyType& A) {324}325 326void PositiveNonConstDeclaration(ExpensiveToCopyType A);327// CHECK-FIXES: void PositiveNonConstDeclaration(const ExpensiveToCopyType& A);328void PositiveNonConstDeclaration(const ExpensiveToCopyType A) {329  // CHECK-MESSAGES: [[@LINE-1]]:60: warning: the const qualified parameter 'A' of type 'const ExpensiveToCopyType'330  // CHECK-FIXES: void PositiveNonConstDeclaration(const ExpensiveToCopyType& A) {331}332 333void PositiveOnlyMessageAsReferencedInCompilationUnit(ExpensiveToCopyType A) {334  // CHECK-MESSAGES: [[@LINE-1]]:75: warning: the parameter 'A' of type 'ExpensiveToCopyType' is copied335  // CHECK-FIXES: void PositiveOnlyMessageAsReferencedInCompilationUnit(const ExpensiveToCopyType& A) {336}337 338void PositiveMessageAndFixAsFunctionIsCalled(ExpensiveToCopyType A) {339  // CHECK-MESSAGES: [[@LINE-1]]:66: warning: the parameter 'A' of type 'ExpensiveToCopyType' is copied340  // CHECK-FIXES: void PositiveMessageAndFixAsFunctionIsCalled(const ExpensiveToCopyType& A) {341}342 343void ReferenceFunctionByCallingIt() {344  PositiveMessageAndFixAsFunctionIsCalled(ExpensiveToCopyType());345}346 347// Virtual method overrides of dependent types cannot be recognized unless they348// are marked as override or final. Test that check is not triggered on methods349// marked with override or final.350template <typename T>351struct NegativeDependentTypeInterface {352  virtual void Method(ExpensiveToCopyType E) = 0;353};354 355template <typename T>356struct NegativeOverrideImpl : public NegativeDependentTypeInterface<T> {357  void Method(ExpensiveToCopyType E) override {}358};359 360template <typename T>361struct NegativeFinalImpl : public NegativeDependentTypeInterface<T> {362  void Method(ExpensiveToCopyType E) final {}363};364 365struct PositiveConstructor {366  PositiveConstructor(ExpensiveToCopyType E) : E(E) {}367  // CHECK-MESSAGES: [[@LINE-1]]:43: warning: the parameter 'E' of type 'ExpensiveToCopyType' is copied368  // CHECK-FIXES: PositiveConstructor(const ExpensiveToCopyType& E) : E(E) {}369 370  ExpensiveToCopyType E;371};372 373struct NegativeUsingConstructor : public PositiveConstructor {374  using PositiveConstructor::PositiveConstructor;375};376 377void fun() {378  ExpensiveToCopyType E;379  NegativeUsingConstructor S(E);380}381 382struct B {383  static void bar(ExpensiveMovableType a, ExpensiveMovableType b);384};385 386template <typename T>387void NegativeCallWithDependentAndNondependentArgs(ExpensiveMovableType a, T b) {388    B::bar(std::move(a), b);389}390