1 // RUN: %check_clang_tidy -std=c++11,c++14,c++17 %s modernize-use-default-member-init %t 2 // FIXME: Fix the checker to work in C++2a mode. 3 4 struct S { 5 }; 6 7 struct PositiveValueChar { PositiveValueCharPositiveValueChar8 PositiveValueChar() : c0(), c1()/*, c2(), c3()*/ {} 9 // CHECK-FIXES: PositiveValueChar() {} 10 const char c0; 11 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use default member initializer for 'c0' [modernize-use-default-member-init] 12 // CHECK-FIXES: const char c0{}; 13 wchar_t c1; 14 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use default member initializer for 'c1' 15 // CHECK-FIXES: wchar_t c1{}; 16 // FIXME: char16_t c2; 17 // C HECK-MESSAGES: :[[@LINE-1]]:12: warning: use default member initializer for 'c2' 18 // C HECK-FIXES: char16_t c2{}; 19 // FIXME: char32_t c3; 20 // C HECK-MESSAGES: :[[@LINE-1]]:12: warning: use default member initializer for 'c3' 21 // C HECK-FIXES: char32_t c3{}; 22 }; 23 24 struct PositiveChar { PositiveCharPositiveChar25 PositiveChar() : d('a') {} 26 // CHECK-FIXES: PositiveChar() {} 27 char d; 28 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'd' 29 // CHECK-FIXES: char d{'a'}; 30 }; 31 32 struct PositiveValueInt { PositiveValueIntPositiveValueInt33 PositiveValueInt() : i() {} 34 // CHECK-FIXES: PositiveValueInt() {} 35 const int i; 36 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use default member initializer for 'i' 37 // CHECK-FIXES: const int i{}; 38 }; 39 40 struct PositiveInt { PositiveIntPositiveInt41 PositiveInt() : j(1) {} 42 // CHECK-FIXES: PositiveInt() {} 43 int j; 44 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j' 45 // CHECK-FIXES: int j{1}; 46 }; 47 48 struct PositiveUnaryMinusInt { PositiveUnaryMinusIntPositiveUnaryMinusInt49 PositiveUnaryMinusInt() : j(-1) {} 50 // CHECK-FIXES: PositiveUnaryMinusInt() {} 51 int j; 52 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j' 53 // CHECK-FIXES: int j{-1}; 54 }; 55 56 struct PositiveUnaryPlusInt { PositiveUnaryPlusIntPositiveUnaryPlusInt57 PositiveUnaryPlusInt() : j(+1) {} 58 // CHECK-FIXES: PositiveUnaryPlusInt() {} 59 int j; 60 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'j' 61 // CHECK-FIXES: int j{+1}; 62 }; 63 64 struct PositiveValueComplexInt { PositiveValueComplexIntPositiveValueComplexInt65 PositiveValueComplexInt() : i() {} 66 // CHECK-FIXES: PositiveValueComplexInt() {} 67 _Complex int i; 68 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use default member initializer for 'i' 69 // CHECK-FIXES: _Complex int i{}; 70 }; 71 72 struct PositiveValueFloat { PositiveValueFloatPositiveValueFloat73 PositiveValueFloat() : f() {} 74 // CHECK-FIXES: PositiveValueFloat() {} 75 float f; 76 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use default member initializer for 'f' 77 // CHECK-FIXES: float f{}; 78 }; 79 80 struct PositiveValueDouble { PositiveValueDoublePositiveValueDouble81 PositiveValueDouble() : d() {} 82 // CHECK-FIXES: PositiveValueDouble() {} 83 double d; 84 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'd' 85 // CHECK-FIXES: double d{}; 86 }; 87 88 struct PositiveDouble { PositiveDoublePositiveDouble89 PositiveDouble() : f(2.5463e43) {} 90 // CHECK-FIXES: PositiveDouble() {} 91 double f; 92 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f' 93 // CHECK-FIXES: double f{2.5463e43}; 94 }; 95 96 struct PositiveValueComplexFloat { PositiveValueComplexFloatPositiveValueComplexFloat97 PositiveValueComplexFloat() : f() {} 98 // CHECK-FIXES: PositiveValueComplexFloat() {} 99 _Complex float f; 100 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use default member initializer for 'f' 101 // CHECK-FIXES: _Complex float f{}; 102 }; 103 104 struct PositiveValueComplexDouble { PositiveValueComplexDoublePositiveValueComplexDouble105 PositiveValueComplexDouble() : f() {} 106 // CHECK-FIXES: PositiveValueComplexDouble() {} 107 _Complex double f; 108 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use default member initializer for 'f' 109 // CHECK-FIXES: _Complex double f{}; 110 }; 111 112 struct PositiveUnaryMinusDouble { PositiveUnaryMinusDoublePositiveUnaryMinusDouble113 PositiveUnaryMinusDouble() : f(-2.5463e43) {} 114 // CHECK-FIXES: PositiveUnaryMinusDouble() {} 115 double f; 116 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f' 117 // CHECK-FIXES: double f{-2.5463e43}; 118 }; 119 120 struct PositiveUnaryPlusDouble { PositiveUnaryPlusDoublePositiveUnaryPlusDouble121 PositiveUnaryPlusDouble() : f(+2.5463e43) {} 122 // CHECK-FIXES: PositiveUnaryPlusDouble() {} 123 double f; 124 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use default member initializer for 'f' 125 // CHECK-FIXES: double f{+2.5463e43}; 126 }; 127 128 struct PositiveValueBool { PositiveValueBoolPositiveValueBool129 PositiveValueBool() : b() {} 130 // CHECK-FIXES: PositiveValueBool() {} 131 bool b; 132 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'b' 133 // CHECK-FIXES: bool b{}; 134 }; 135 136 struct PositiveBool { PositiveBoolPositiveBool137 PositiveBool() : a(true) {} 138 // CHECK-FIXES: PositiveBool() {} 139 bool a; 140 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'a' 141 // CHECK-FIXES: bool a{true}; 142 }; 143 144 struct PositiveValuePointer { PositiveValuePointerPositiveValuePointer145 PositiveValuePointer() : p() {} 146 // CHECK-FIXES: PositiveValuePointer() {} 147 int *p; 148 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'p' 149 // CHECK-FIXES: int *p{}; 150 }; 151 152 struct PositiveNullPointer { PositiveNullPointerPositiveNullPointer153 PositiveNullPointer() : q(nullptr) {} 154 // CHECK-FIXES: PositiveNullPointer() {} 155 int *q; 156 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'q' 157 // CHECK-FIXES: int *q{nullptr}; 158 }; 159 160 enum Enum { Foo, Bar }; 161 struct PositiveEnum { PositiveEnumPositiveEnum162 PositiveEnum() : e(Foo) {} 163 // CHECK-FIXES: PositiveEnum() {} 164 Enum e; 165 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e' 166 // CHECK-FIXES: Enum e{Foo}; 167 }; 168 169 struct PositiveValueEnum { PositiveValueEnumPositiveValueEnum170 PositiveValueEnum() : e() {} 171 // CHECK-FIXES: PositiveValueEnum() {} 172 Enum e; 173 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e' 174 // CHECK-FIXES: Enum e{}; 175 }; 176 177 struct PositiveString { PositiveStringPositiveString178 PositiveString() : s("foo") {} 179 // CHECK-FIXES: PositiveString() {} 180 const char *s; 181 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use default member initializer for 's' 182 // CHECK-FIXES: const char *s{"foo"}; 183 }; 184 185 struct PositiveStruct { PositiveStructPositiveStruct186 PositiveStruct() : s(7) {} 187 // CHECK-FIXES: PositiveStruct() {} 188 struct { 189 int s; 190 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use default member initializer for 's' 191 // CHECK-FIXES: int s{7}; 192 }; 193 }; 194 195 template <typename T> 196 struct NegativeTemplate { NegativeTemplateNegativeTemplate197 NegativeTemplate() : t() {} 198 T t; 199 }; 200 201 NegativeTemplate<int> nti; 202 NegativeTemplate<double> ntd; 203 204 struct NegativeDefaultMember { NegativeDefaultMemberNegativeDefaultMember205 NegativeDefaultMember() {} 206 int i = 2; 207 }; 208 209 struct NegativeClass : S { NegativeClassNegativeClass210 NegativeClass() : s() {} 211 S s; 212 }; 213 214 struct NegativeBase : S { NegativeBaseNegativeBase215 NegativeBase() : S() {} 216 }; 217 218 struct NegativeDefaultOtherMember{ NegativeDefaultOtherMemberNegativeDefaultOtherMember219 NegativeDefaultOtherMember() : i(3) {} 220 int i = 4; 221 }; 222 223 struct NegativeUnion { NegativeUnionNegativeUnion224 NegativeUnion() : d(5.0) {} 225 union { 226 int i; 227 double d; 228 }; 229 }; 230 231 struct NegativeBitField 232 { NegativeBitFieldNegativeBitField233 NegativeBitField() : i(6) {} 234 int i : 5; 235 }; 236 237 struct NegativeNotDefaultInt 238 { NegativeNotDefaultIntNegativeNotDefaultInt239 NegativeNotDefaultInt(int) : i(7) {} 240 int i; 241 }; 242 243 struct NegativeDefaultArg 244 { NegativeDefaultArgNegativeDefaultArg245 NegativeDefaultArg(int i = 4) : i(i) {} 246 int i; 247 }; 248 249 struct ExistingChar { ExistingCharExistingChar250 ExistingChar(short) : e1(), e2{}, e3(), e4() {} 251 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant [modernize-use-default-member-init] 252 // CHECK-MESSAGES: :[[@LINE-2]]:31: warning: member initializer for 'e2' is redundant 253 // CHECK-MESSAGES: :[[@LINE-3]]:37: warning: member initializer for 'e3' is redundant 254 // CHECK-FIXES: ExistingChar(short) : e4() {} ExistingCharExistingChar255 ExistingChar(int) : e1(0), e2{0}, e3(0), e4(0) {} 256 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: member initializer for 'e1' is redundant 257 // CHECK-MESSAGES: :[[@LINE-2]]:30: warning: member initializer for 'e2' is redundant 258 // CHECK-MESSAGES: :[[@LINE-3]]:37: warning: member initializer for 'e3' is redundant 259 // CHECK-FIXES: ExistingChar(int) : e4(0) {} ExistingCharExistingChar260 ExistingChar(long) : e1('\0'), e2{'\0'}, e3('\0'), e4('\0') {} 261 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: member initializer for 'e1' is redundant 262 // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: member initializer for 'e2' is redundant 263 // CHECK-MESSAGES: :[[@LINE-3]]:44: warning: member initializer for 'e3' is redundant 264 // CHECK-FIXES: ExistingChar(long) : e4('\0') {} ExistingCharExistingChar265 ExistingChar(char) : e1('a'), e2{'a'}, e3('a'), e4('a') {} 266 // CHECK-MESSAGES: :[[@LINE-1]]:51: warning: member initializer for 'e4' is redundant 267 // CHECK-FIXES: ExistingChar(char) : e1('a'), e2{'a'}, e3('a') {} 268 char e1{}; 269 char e2 = 0; 270 char e3 = '\0'; 271 char e4 = 'a'; 272 }; 273 274 struct ExistingInt { ExistingIntExistingInt275 ExistingInt(short) : e1(), e2{}, e3(), e4(), e5(), e6() {} 276 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: member initializer for 'e1' is redundant [modernize-use-default-member-init] 277 // CHECK-MESSAGES: :[[@LINE-2]]:30: warning: member initializer for 'e2' is redundant 278 // CHECK-FIXES: ExistingInt(short) : e3(), e4(), e5(), e6() {} ExistingIntExistingInt279 ExistingInt(int) : e1(0), e2{0}, e3(0), e4(0), e5(0), e6(0) {} 280 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: member initializer for 'e1' is redundant 281 // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: member initializer for 'e2' is redundant 282 // CHECK-FIXES: ExistingInt(int) : e3(0), e4(0), e5(0), e6(0) {} ExistingIntExistingInt283 ExistingInt(long) : e1(5), e2{5}, e3(5), e4(5), e5(5), e6(5) {} 284 // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: member initializer for 'e3' is redundant 285 // CHECK-MESSAGES: :[[@LINE-2]]:44: warning: member initializer for 'e4' is redundant 286 // CHECK-MESSAGES: :[[@LINE-3]]:58: warning: member initializer for 'e6' is redundant 287 // CHECK-FIXES: ExistingInt(long) : e1(5), e2{5}, e5(5) {} ExistingIntExistingInt288 ExistingInt(char) : e1(-5), e2{-5}, e3(-5), e4(-5), e5(-5), e6(-5) {} 289 // CHECK-MESSAGES: :[[@LINE-1]]:55: warning: member initializer for 'e5' is redundant 290 // CHECK-FIXES: ExistingInt(char) : e1(-5), e2{-5}, e3(-5), e4(-5), e6(-5) {} 291 int e1{}; 292 int e2 = 0; 293 int e3 = {5}; 294 int e4{5}; 295 int e5 = -5; 296 int e6 = +5; 297 }; 298 299 struct ExistingDouble { ExistingDoubleExistingDouble300 ExistingDouble(short) : e1(), e2{}, e3(), e4(), e5() {} 301 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: member initializer for 'e1' is redundant 302 // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: member initializer for 'e2' is redundant 303 // CHECK-FIXES: ExistingDouble(short) : e3(), e4(), e5() {} ExistingDoubleExistingDouble304 ExistingDouble(int) : e1(0.0), e2{0.0}, e3(0.0), e4(0.0), e5(0.0) {} 305 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant 306 // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: member initializer for 'e2' is redundant 307 // CHECK-FIXES: ExistingDouble(int) : e3(0.0), e4(0.0), e5(0.0) {} ExistingDoubleExistingDouble308 ExistingDouble(long) : e1(5.0), e2{5.0}, e3(5.0), e4(5.0), e5(5.0) {} 309 // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: member initializer for 'e3' is redundant 310 // CHECK-MESSAGES: :[[@LINE-2]]:62: warning: member initializer for 'e5' is redundant 311 // CHECK-FIXES: ExistingDouble(long) : e1(5.0), e2{5.0}, e4(5.0) {} ExistingDoubleExistingDouble312 ExistingDouble(char) : e1(-5.0), e2{-5.0}, e3(-5.0), e4(-5.0), e5(-5.0) {} 313 // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: member initializer for 'e4' is redundant 314 // CHECK-FIXES: ExistingDouble(char) : e1(-5.0), e2{-5.0}, e3(-5.0), e5(-5.0) {} 315 double e1{}; 316 double e2 = 0.0; 317 double e3 = 5.0; 318 double e4{-5.0}; 319 double e5 = +5.0; 320 }; 321 322 struct ExistingBool { ExistingBoolExistingBool323 ExistingBool(short) : e1(), e2{}, e3() {} 324 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant 325 // CHECK-MESSAGES: :[[@LINE-2]]:31: warning: member initializer for 'e2' is redundant 326 // CHECK-FIXES: ExistingBool(short) : e3() {} ExistingBoolExistingBool327 ExistingBool(int) : e1(false), e2{false}, e3(false) {} 328 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: member initializer for 'e1' is redundant 329 // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: member initializer for 'e2' is redundant 330 // CHECK-FIXES: ExistingBool(int) : e3(false) {} ExistingBoolExistingBool331 ExistingBool(long) : e1(true), e2{true}, e3(true) {} 332 // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: member initializer for 'e3' is redundant 333 // CHECK-FIXES: ExistingBool(long) : e1(true), e2{true} {} 334 bool e1{}; 335 bool e2 = false; 336 bool e3{true}; 337 }; 338 339 struct ExistingEnum { ExistingEnumExistingEnum340 ExistingEnum(short) : e1(Foo), e2{Foo} {} 341 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant 342 // CHECK-FIXES: ExistingEnum(short) : e2{Foo} {} ExistingEnumExistingEnum343 ExistingEnum(int) : e1(Bar), e2{Bar} {} 344 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: member initializer for 'e2' is redundant 345 // CHECK-FIXES: ExistingEnum(int) : e1(Bar) {} 346 Enum e1 = Foo; 347 Enum e2{Bar}; 348 }; 349 350 struct ExistingPointer { ExistingPointerExistingPointer351 ExistingPointer(short) : e1(), e2{}, e3(), e4() {} 352 // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: member initializer for 'e1' is redundant 353 // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: member initializer for 'e2' is redundant 354 // CHECK-MESSAGES: :[[@LINE-3]]:40: warning: member initializer for 'e3' is redundant 355 // CHECK-FIXES: ExistingPointer(short) : e4() {} ExistingPointerExistingPointer356 ExistingPointer(int) : e1(0), e2{0}, e3(0), e4(&e1) {} 357 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: member initializer for 'e1' is redundant 358 // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: member initializer for 'e2' is redundant 359 // CHECK-MESSAGES: :[[@LINE-3]]:40: warning: member initializer for 'e3' is redundant 360 // CHECK-FIXES: ExistingPointer(int) : e4(&e1) {} ExistingPointerExistingPointer361 ExistingPointer(long) : e1(nullptr), e2{nullptr}, e3(nullptr), e4(&e2) {} 362 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: member initializer for 'e1' is redundant 363 // CHECK-MESSAGES: :[[@LINE-2]]:40: warning: member initializer for 'e2' is redundant 364 // CHECK-MESSAGES: :[[@LINE-3]]:53: warning: member initializer for 'e3' is redundant 365 // CHECK-FIXES: ExistingPointer(long) : e4(&e2) {} 366 int *e1{}; 367 int *e2 = 0; 368 int *e3{nullptr}; 369 int **e4 = &e1; 370 }; 371 372 struct ExistingString { ExistingStringExistingString373 ExistingString(short) : e1(), e2{}, e3(), e4() {} 374 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: member initializer for 'e1' is redundant [modernize-use-default-member-init] 375 // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: member initializer for 'e2' is redundant 376 // CHECK-FIXES: ExistingString(short) : e3(), e4() {} ExistingStringExistingString377 ExistingString(int) : e1(0), e2{0}, e3(0), e4(0) {} 378 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: member initializer for 'e1' is redundant 379 // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: member initializer for 'e2' is redundant 380 // CHECK-FIXES: ExistingString(int) : e3(0), e4(0) {} ExistingStringExistingString381 ExistingString(long) : e1(nullptr), e2{nullptr}, e3(nullptr), e4(nullptr) {} 382 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: member initializer for 'e1' is redundant 383 // CHECK-MESSAGES: :[[@LINE-2]]:39: warning: member initializer for 'e2' is redundant 384 // CHECK-FIXES: ExistingString(long) : e3(nullptr), e4(nullptr) {} ExistingStringExistingString385 ExistingString(char) : e1("foo"), e2{"foo"}, e3("foo"), e4("foo") {} 386 // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: member initializer for 'e3' is redundant 387 // CHECK-FIXES: ExistingString(char) : e1("foo"), e2{"foo"}, e4("foo") {} 388 const char *e1{}; 389 const char *e2 = nullptr; 390 const char *e3 = "foo"; 391 const char *e4 = "bar"; 392 }; 393 394 struct UnionExisting { UnionExistingUnionExisting395 UnionExisting() : e(5.0) {} 396 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: member initializer for 'e' is redundant 397 // CHECK-FIXES: UnionExisting() {} 398 union { 399 int i; 400 double e = 5.0; 401 }; 402 }; 403 404 template <typename T> 405 struct NegativeTemplateExisting { NegativeTemplateExistingNegativeTemplateExisting406 NegativeTemplateExisting(int) : t(0) {} 407 T t{}; 408 }; 409 410 NegativeTemplateExisting<int> ntei(0); 411 NegativeTemplateExisting<double> nted(0); 412 413 // This resulted in a warning by default. 414 #define MACRO() \ 415 struct MacroS { \ 416 void *P; \ 417 MacroS() : P(nullptr) {} \ 418 }; 419 420 MACRO(); 421