brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · d7a5797 Raw
187 lines · cpp
1// RUN: %check_clang_tidy %s misc-unconventional-assign-operator %t -- -- -fno-delayed-template-parsing2 3namespace std {4template <typename T>5struct remove_reference { typedef T type; };6template <typename T>7struct remove_reference<T &> { typedef T type; };8template <typename T>9struct remove_reference<T &&> { typedef T type; };10template <typename T>11typename remove_reference<T>::type &&move(T &&t);12}13 14 15struct Good {16  Good& operator=(const Good&);17  Good& operator=(Good&&);18 19  // Assign from other types is fine too.20  Good& operator=(int);21};22 23struct AlsoGood {24  // By value is also fine.25  AlsoGood& operator=(AlsoGood);26};27 28struct BadReturnType {29  void operator=(const BadReturnType&);30  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'BadReturnType&' [misc-unconventional-assign-operator]31  const BadReturnType& operator=(BadReturnType&&);32  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad33  void operator=(int);34  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad35};36 37struct BadReturnType2 {38  BadReturnType2&& operator=(const BadReturnType2&);39  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad40  int operator=(BadReturnType2&&);41  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad42};43 44struct BadArgument {45  BadArgument& operator=(BadArgument&);46  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadArgument const&', 'BadArgument&&' or 'BadArgument'47  BadArgument& operator=(const BadArgument&&);48  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadArgument const&', 'BadArgument&&' or 'BadArgument'49};50 51struct BadModifier {52  BadModifier& operator=(const BadModifier&) const;53  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'const'54};55 56struct Deleted {57  // We don't check the return value of deleted operators.58  void operator=(const Deleted&) = delete;59  void operator=(Deleted&&) = delete;60};61 62class Private {63  // We don't check the return value of private operators.64  // Pre-C++11 way of disabling assignment.65  void operator=(const Private &);66};67 68struct Virtual {69  virtual Virtual& operator=(const Virtual &);70  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'virtual'71};72 73class BadReturnStatement {74  int n;75 76public:77  BadReturnStatement& operator=(BadReturnStatement&& rhs) {78    n = std::move(rhs.n);79    return *&rhs;80// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: operator=() should always return '*this'81  }82 83  // Do not check if return type is different from '&BadReturnStatement'84  int operator=(int i) {85  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad86    n = i;87    return n;88  }89};90 91namespace pr31531 {92enum E { e };93// This declaration makes the 'return *this' below have an unresolved operator94// in the class template, but not in an instantiation.95E operator*(E, E);96 97template <typename>98struct UnresolvedOperator {99  UnresolvedOperator &operator=(const UnresolvedOperator &) { return *this; }100};101 102UnresolvedOperator<int> UnresolvedOperatorInt;103 104template <typename>105struct Template {106  Template &operator=(const Template &) { return this; }107  // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: operator=() should always return '*this'108};109 110Template<int> TemplateInt;111}112 113struct AssignmentCallAtReturn {114  AssignmentCallAtReturn &returnThis() {115    return *this;116  }117  AssignmentCallAtReturn &operator=(int rhs) {118    return *this;119  }120  AssignmentCallAtReturn &operator=(char rhs) {121    // Allow call to assignment from other type.122    return (*this = static_cast<int>(rhs));123  }124  AssignmentCallAtReturn &operator=(float rhs) {125    // Do not allow calls to other functions.126    return returnThis();127    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: operator=() should always return '*this'128  }129};130 131// Check that no false positives are issued when using type aliases.132struct TypeAlias {133  using Alias = TypeAlias;134  // This is correct and should not produce any warnings:135  Alias &operator=(const Alias &) { return *this; }136 137  using AliasRef = Alias &;138  // So is this (assignments from other types are fine):139  AliasRef operator=(int) { return *this; }140};141 142// Same check as above with typedef instead of using143struct TypeAliasTypedef {144  typedef TypeAliasTypedef Alias;145  Alias &operator=(const Alias &) { return *this; }146 147  typedef Alias &AliasRef;148  AliasRef operator=(int) { return *this; }149};150 151// Same check as above for a template class152template <typename T>153struct TemplateTypeAlias {154  using Alias1 = TemplateTypeAlias &;155  using Alias2 = TemplateTypeAlias const &;156  Alias1 operator=(Alias2) { return *this; }157 158  template <typename U>159  using Alias3 = TemplateTypeAlias<U>;160  Alias3<T> &operator=(int) { return *this; }161 162  // Using a different type parameter in the return type should give a warning163  Alias3<TypeAlias::Alias> &operator=(double) { return *this; }164  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'TemplateTypeAlias&' [misc-unconventional-assign-operator]165};166 167namespace gh143237 {168template<typename T>169struct TemplateAssignment {170  explicit TemplateAssignment(int) {171  }172 173  TemplateAssignment& operator=(int n) {174    // No warning175    return *this = TemplateAssignment(n);176  }177};178}179 180namespace GH153770 {181  struct A;182  struct A {183    A() = default;184    A& operator=(const A&) = default;185  };186} // namespace GH153770187