1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
// RUN: %check_clang_tidy %s misc-unconventional-assign-operator %t -- -- -isystem %S/Inputs/Headers -fno-delayed-template-parsing
namespace std {
template <typename T>
struct remove_reference { typedef T type; };
template <typename T>
struct remove_reference<T &> { typedef T type; };
template <typename T>
struct remove_reference<T &&> { typedef T type; };
template <typename T>
typename remove_reference<T>::type &&move(T &&t);
}
struct Good {
Good& operator=(const Good&);
Good& operator=(Good&&);
// Assign from other types is fine too.
Good& operator=(int);
};
struct AlsoGood {
// By value is also fine.
AlsoGood& operator=(AlsoGood);
};
struct BadReturnType {
void operator=(const BadReturnType&);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'BadReturnType&' [misc-unconventional-assign-operator]
const BadReturnType& operator=(BadReturnType&&);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
void operator=(int);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
};
struct BadReturnType2 {
BadReturnType2&& operator=(const BadReturnType2&);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
int operator=(BadReturnType2&&);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
};
struct BadArgument {
BadArgument& operator=(BadArgument&);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadArgument const&', 'BadArgument&&' or 'BadArgument'
BadArgument& operator=(const BadArgument&&);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadAr
};
struct BadModifier {
BadModifier& operator=(const BadModifier&) const;
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'const'
};
struct Deleted {
// We don't check the return value of deleted operators.
void operator=(const Deleted&) = delete;
void operator=(Deleted&&) = delete;
};
class Private {
// We don't check the return value of private operators.
// Pre-C++11 way of disabling assignment.
void operator=(const Private &);
};
struct Virtual {
virtual Virtual& operator=(const Virtual &);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'virtual'
};
class BadReturnStatement {
int n;
public:
BadReturnStatement& operator=(BadReturnStatement&& rhs) {
n = std::move(rhs.n);
return rhs;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: operator=() should always return '*this'
}
// Do not check if return type is different from '&BadReturnStatement'
int operator=(int i) {
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
n = i;
return n;
}
};
namespace pr31531 {
enum E { e };
// This declaration makes the 'return *this' below have an unresolved operator
// in the class template, but not in an instantiation.
E operator*(E, E);
template <typename>
struct UnresolvedOperator {
UnresolvedOperator &operator=(const UnresolvedOperator &) { return *this; }
};
UnresolvedOperator<int> UnresolvedOperatorInt;
template <typename>
struct Template {
Template &operator=(const Template &) { return this; }
// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: operator=() should always return '*this'
};
Template<int> TemplateInt;
}
struct AssignmentCallAtReturn {
AssignmentCallAtReturn &returnThis() {
return *this;
}
AssignmentCallAtReturn &operator=(int rhs) {
return *this;
}
AssignmentCallAtReturn &operator=(char rhs) {
// Allow call to assignment from other type.
return (*this = static_cast<int>(rhs));
}
AssignmentCallAtReturn &operator=(float rhs) {
// Do not allow calls to other functions.
return returnThis();
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: operator=() should always return '*this'
}
};
|