1 // RUN: %check_clang_tidy %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions 2 3 // Out of line definition. 4 class OL { 5 public: 6 OL(); 7 ~OL(); 8 }; 9 OL()10OL::OL() {}; 11 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial default constructor [modernize-use-equals-default] 12 // CHECK-FIXES: OL::OL() = default; ~OL()13OL::~OL() {} 14 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial destructor [modernize-use-equals-default] 15 // CHECK-FIXES: OL::~OL() = default; 16 17 // Inline definitions. 18 class IL { 19 public: IL()20 IL() {} ; // Note embedded tab on this line 21 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 22 // CHECK-FIXES: IL() = default ; // Note embedded tab on this line ~IL()23 ~IL() {} 24 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 25 // CHECK-FIXES: ~IL() = default; 26 }; 27 28 // Non-empty body. 29 void f(); 30 class NE { 31 public: NE()32 NE() { f(); } ~NE()33 ~NE() { f(); } 34 }; 35 36 // Skip unions. 37 union NU { NU()38 NU() {} 39 // CHECK-FIXES: NU() {} ~NU()40 ~NU() {} 41 // CHECK-FIXES: ~NU() {} 42 NE Field; 43 }; 44 45 // Skip unions with out-of-line constructor/destructor. 46 union NUO { 47 NUO(); 48 ~NUO(); 49 NE Field; 50 }; 51 NUO()52NUO::NUO() {} 53 // CHECK-FIXES: NUO::NUO() {} ~NUO()54NUO::~NUO() {} 55 // CHECK-FIXES: NUO::~NUO() {} 56 57 // Skip structs/classes containing anonymous unions. 58 struct SU { SUSU59 SU() {} 60 // CHECK-FIXES: SU() {} ~SUSU61 ~SU() {} 62 // CHECK-FIXES: ~SU() {} 63 union { 64 NE Field; 65 }; 66 }; 67 68 // Skip variadic constructors. 69 struct VA { VAVA70 VA(...) {} 71 }; 72 73 // Skip template constructors. 74 struct TC { 75 template <unsigned U> TCTC76 TC() {} 77 78 template <unsigned U> TCTC79 TC(const TC &) {} 80 81 template <unsigned U> operator =TC82 TC& operator = (const TC &) { return *this; } 83 }; 84 85 // Initializer or arguments. 86 class IA { 87 public: 88 // Constructor with initializer. IA()89 IA() : Field(5) {} 90 // Constructor with arguments. IA(int Arg1,int Arg2)91 IA(int Arg1, int Arg2) {} 92 int Field; 93 }; 94 95 // Default member initializer 96 class DMI { 97 public: DMI()98 DMI() {} // Comment before semi-colon on next line 99 ; 100 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default' 101 // CHECK-FIXES: DMI() = default // Comment before semi-colon on next line 102 // CHECK-FIXES-NEXT: ; 103 int Field = 5; 104 }; 105 106 // Class member 107 class CM { 108 public: CM()109 CM() {} /* Comments */ /* before */ /* semicolon */; 110 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 111 // CHECK-FIXES: CM() = default /* Comments */ /* before */ /* semicolon */; 112 OL o; 113 }; 114 115 // Private constructor/destructor. 116 class Priv { 117 Priv(); ~Priv()118 ~Priv() {} 119 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 120 // CHECK-FIXES: ~Priv() = default; 121 }; 122 Priv()123Priv::Priv() {} 124 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use '= default' 125 // CHECK-FIXES: Priv::Priv() = default; 126 127 struct SemiColon { SemiColonSemiColon128 SemiColon() {}; 129 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 130 // CHECK-FIXES: SemiColon() = default;{{$}} 131 }; 132 133 struct SemiColonOutOfLine { 134 SemiColonOutOfLine(); 135 }; 136 SemiColonOutOfLine()137SemiColonOutOfLine::SemiColonOutOfLine() {}; 138 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use '= default' 139 // CHECK-FIXES: SemiColonOutOfLine::SemiColonOutOfLine() = default;{{$}} 140 141 // struct. 142 struct ST { STST143 ST() {} 144 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 145 // CHECK-FIXES: ST() = default;{{$}} ~STST146 ~ST() {} 147 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 148 // CHECK-FIXES: ST() = default;{{$}} 149 }; 150 151 // Deleted constructor/destructor. 152 class Del { 153 public: 154 Del() = delete; 155 ~Del() = delete; 156 }; 157 158 // Do not remove other keywords. 159 class KW { 160 public: KW()161 explicit KW() {} 162 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use '= default' 163 // CHECK-FIXES: explicit KW() = default; ~KW()164 virtual ~KW() {} 165 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use '= default' 166 // CHECK-FIXES: virtual ~KW() = default; 167 }; 168 169 // Nested class. 170 struct N { 171 struct NN { NNN::NN172 NN() {} 173 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' 174 // CHECK-FIXES: NN() = default; ~NNN::NN175 ~NN() {} 176 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' 177 // CHECK-FIXES: ~NN() = default; 178 }; 179 int Int; 180 }; 181 182 // Class template. 183 template <class T> 184 class Temp { 185 public: Temp()186 Temp() {} 187 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 188 // CHECK-FIXES: Temp() = default; ~Temp()189 ~Temp() {} 190 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 191 // CHECK-FIXES: ~Temp() = default; 192 }; 193 194 // Class template out of line with explicit instantiation. 195 template <class T> 196 class TempODef { 197 public: 198 TempODef(); 199 ~TempODef(); 200 }; 201 202 template <class T> TempODef()203TempODef<T>::TempODef() {} 204 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use '= default' 205 // CHECK-FIXES: TempODef<T>::TempODef() = default; 206 template <class T> ~TempODef()207TempODef<T>::~TempODef() {} 208 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use '= default' 209 // CHECK-FIXES: TempODef<T>::~TempODef() = default; 210 211 template class TempODef<int>; 212 template class TempODef<double>; 213 214 // Non user-provided constructor/destructor. 215 struct Imp { 216 int Int; 217 }; g()218void g() { 219 Imp *PtrImp = new Imp(); 220 PtrImp->~Imp(); 221 delete PtrImp; 222 } 223 224 // Already using default. 225 struct IDef { 226 IDef() = default; 227 ~IDef() = default; 228 }; 229 struct ODef { 230 ODef(); 231 ~ODef(); 232 }; 233 ODef::ODef() = default; 234 ODef::~ODef() = default; 235 236 // Delegating constructor and overriden destructor. 237 struct DC : KW { DCDC238 DC() : KW() {} ~DCDC239 ~DC() override {} 240 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 241 // CHECK-FIXES: ~DC() override = default;{{$}} 242 }; 243 244 struct OverrideWithSemiColon : KW { ~OverrideWithSemiColonOverrideWithSemiColon245 ~OverrideWithSemiColon() override {}; 246 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 247 // CHECK-FIXES: ~OverrideWithSemiColon() override = default;{{$}} 248 }; 249 250 struct Comments { CommentsComments251 Comments() { 252 // Don't erase comments inside the body. 253 } 254 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default' ~CommentsComments255 ~Comments() { 256 // Don't erase comments inside the body. 257 } 258 // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default' 259 }; 260 261 // Try-catch. 262 struct ITC { ITCITC263 ITC() try {} catch(...) {} ~ITCITC264 ~ITC() try {} catch(...) {} 265 }; 266 267 struct OTC { 268 OTC(); 269 ~OTC(); 270 }; OTC()271OTC::OTC() try {} catch(...) {} ~OTC()272OTC::~OTC() try {} catch(...) {} 273 274 #define STRUCT_WITH_DEFAULT(_base, _type) \ 275 struct _type { \ 276 _type() {} \ 277 _base value; \ 278 }; 279 280 STRUCT_WITH_DEFAULT(unsigned char, InMacro) 281 282 #define ZERO_VALUE 0 283 struct PreprocesorDependentTest 284 { 285 void something(); 286 PreprocesorDependentTestPreprocesorDependentTest287 PreprocesorDependentTest() { 288 #if ZERO_VALUE 289 something(); 290 #endif 291 } 292 ~PreprocesorDependentTestPreprocesorDependentTest293 ~PreprocesorDependentTest() { 294 #if ZERO_VALUE 295 something(); 296 #endif 297 } 298 }; 299