189 lines · cpp
1// RUN: %check_clang_tidy %s google-explicit-constructor %t2 3namespace std {4 typedef decltype(sizeof(int)) size_t;5 6 // libc++'s implementation7 template <class _E>8 class initializer_list9 {10 const _E* __begin_;11 size_t __size_;12 13 initializer_list(const _E* __b, size_t __s)14 : __begin_(__b),15 __size_(__s)16 {}17 18 public:19 typedef _E value_type;20 typedef const _E& reference;21 typedef const _E& const_reference;22 typedef size_t size_type;23 24 typedef const _E* iterator;25 typedef const _E* const_iterator;26 27 initializer_list() : __begin_(nullptr), __size_(0) {}28 29 size_t size() const {return __size_;}30 const _E* begin() const {return __begin_;}31 const _E* end() const {return __begin_ + __size_;}32 };33}34 35struct A {36 A() {}37 A(int x, int y) {}38 39 explicit A(void *x) {}40 explicit A(void *x, void *y) {}41 explicit operator bool() const { return true; }42 43 operator double() const = delete;44 45 explicit A(const A& a) {}46 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: copy constructor should not be declared explicit [google-explicit-constructor]47 // CHECK-FIXES: A(const A& a) {}48 49 A(int x1);50 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]51 // CHECK-FIXES: explicit A(int x1);52 53 A(double x2, double y = 3.14) {}54 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructors that are callable with a single argument must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]55 // CHECK-FIXES: explicit A(double x2, double y = 3.14) {}56 57 template <typename... T>58 A(T&&... args);59 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructors that are callable with a single argument60 // CHECK-FIXES: explicit A(T&&... args);61};62 63inline A::A(int x1) {}64 65struct B {66 B(std::initializer_list<int> list1) {}67 B(const std::initializer_list<unsigned> &list2) {}68 B(std::initializer_list<unsigned> &&list3) {}69 70 operator bool() const { return true; }71 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator bool' must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]72 // CHECK-FIXES: explicit operator bool() const { return true; }73 74 operator double() const;75 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator double' must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]76 // CHECK-FIXES: explicit operator double() const;77 78 explicit B(::std::initializer_list<double> list4) {}79 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor should not be declared explicit [google-explicit-constructor]80 // CHECK-FIXES: B(::std::initializer_list<double> list4) {}81 82 explicit B(const ::std::initializer_list<char> &list5) {}83 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor84 // CHECK-FIXES: B(const ::std::initializer_list<char> &list5) {}85 86 explicit B(::std::initializer_list<char> &&list6) {}87 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor88 // CHECK-FIXES: B(::std::initializer_list<char> &&list6) {}89};90 91inline B::operator double() const { return 0.0; }92 93struct StructWithFnPointer {94 void (*f)();95} struct_with_fn_pointer = {[] {}};96 97using namespace std;98 99struct C {100 C(initializer_list<int> list1) {}101 C(const initializer_list<unsigned> &list2) {}102 C(initializer_list<unsigned> &&list3) {}103};104 105template <typename T>106struct C2 {107 C2(initializer_list<int> list1) {}108 C2(const initializer_list<unsigned> &list2) {}109 C2(initializer_list<unsigned> &&list3) {}110 111 explicit C2(initializer_list<double> list4) {}112 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor113 // CHECK-FIXES: C2(initializer_list<double> list4) {}114};115 116template <typename T>117struct C3 {118 C3(initializer_list<T> list1) {}119 C3(const std::initializer_list<T*> &list2) {}120 C3(::std::initializer_list<T**> &&list3) {}121 122 template <typename U>123 C3(initializer_list<U> list3) {}124};125 126struct D {127 template <typename T>128 explicit D(T t) {}129};130 131template <typename T>132struct E {133 E(T *pt) {}134 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors135 // CHECK-FIXES: explicit E(T *pt) {}136 template <typename U>137 E(U *pu) {}138 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors139 // CHECK-FIXES: explicit E(U *pu) {}140 141 explicit E(T t) {}142 template <typename U>143 explicit E(U u) {}144};145 146void f(std::initializer_list<int> list) {147 D d(list);148 E<decltype(list)> e(list);149 E<int> e2(list);150}151 152template <typename T>153struct F {};154 155template<typename T>156struct G {157 operator bool() const;158 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator bool' must be marked159 // CHECK-FIXES: explicit operator bool() const;160 operator F<T>() const;161 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator F<type-parameter-0-0>' must be marked162 // CHECK-FIXES: explicit operator F<T>() const;163 template<typename U>164 operator F<U>*() const;165 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator F<type-parameter-1-0> *' must be marked166 // CHECK-FIXES: explicit operator F<U>*() const;167};168 169void f2() {170 G<int> a;171 (void)(F<int>)a;172 if (a) {}173 (void)(F<int>*)a;174 (void)(F<int*>*)a;175 176 G<double> b;177 (void)(F<double>)b;178 if (b) {}179 (void)(F<double>*)b;180 (void)(F<double*>*)b;181}182 183#define DEFINE_STRUCT_WITH_OPERATOR_BOOL(name) \184 struct name { \185 operator bool() const; \186 }187 188DEFINE_STRUCT_WITH_OPERATOR_BOOL(H);189