1 // RUN: %check_clang_tidy %s modernize-use-emplace %t -- \ 2 // RUN: -config="{CheckOptions: \ 3 // RUN: [{key: modernize-use-emplace.ContainersWithPushBack, \ 4 // RUN: value: '::std::vector; ::std::list; ::std::deque; llvm::LikeASmallVector'}, \ 5 // RUN: {key: modernize-use-emplace.TupleTypes, \ 6 // RUN: value: '::std::pair; std::tuple; ::test::Single'}, \ 7 // RUN: {key: modernize-use-emplace.TupleMakeFunctions, \ 8 // RUN: value: '::std::make_pair; ::std::make_tuple; ::test::MakeSingle'}] \ 9 // RUN: }" 10 11 namespace std { 12 template <typename> 13 class initializer_list { 14 public: 15 initializer_list() noexcept {} 16 }; 17 18 template <typename T1, typename T2> 19 class pair { 20 public: 21 pair() = default; 22 pair(const pair &) = default; 23 pair(pair &&) = default; 24 25 pair(const T1 &, const T2 &) {} 26 pair(T1 &&, T2 &&) {} 27 28 template <typename U1, typename U2> 29 pair(const pair<U1, U2> &){}; 30 template <typename U1, typename U2> 31 pair(pair<U1, U2> &&){}; 32 }; 33 34 template <typename T> 35 class vector { 36 public: 37 using value_type = T; 38 39 class iterator {}; 40 class const_iterator {}; 41 const_iterator begin() { return const_iterator{}; } 42 43 vector() = default; 44 vector(initializer_list<T>) {} 45 46 void push_back(const T &) {} 47 void push_back(T &&) {} 48 49 template <typename... Args> 50 void emplace_back(Args &&... args){}; 51 template <typename... Args> 52 iterator emplace(const_iterator pos, Args &&...args){}; 53 ~vector(); 54 }; 55 56 template <typename T> 57 class list { 58 public: 59 using value_type = T; 60 61 class iterator {}; 62 class const_iterator {}; 63 const_iterator begin() { return const_iterator{}; } 64 65 void push_front(const T &) {} 66 void push_front(T &&) {} 67 68 void push_back(const T &) {} 69 void push_back(T &&) {} 70 71 template <typename... Args> 72 iterator emplace(const_iterator pos, Args &&...args){}; 73 template <typename... Args> 74 void emplace_back(Args &&... args){}; 75 template <typename... Args> 76 void emplace_front(Args &&...args){}; 77 ~list(); 78 }; 79 80 template <typename T> 81 class deque { 82 public: 83 using value_type = T; 84 85 class iterator {}; 86 class const_iterator {}; 87 const_iterator begin() { return const_iterator{}; } 88 89 void push_back(const T &) {} 90 void push_back(T &&) {} 91 92 void push_front(const T &) {} 93 void push_front(T &&) {} 94 95 template <typename... Args> 96 iterator emplace(const_iterator pos, Args &&...args){}; 97 template <typename... Args> 98 void emplace_back(Args &&... args){}; 99 template <typename... Args> 100 void emplace_front(Args &&...args){}; 101 ~deque(); 102 }; 103 104 template <typename T> 105 class forward_list { 106 public: 107 using value_type = T; 108 109 class iterator {}; 110 class const_iterator {}; 111 const_iterator begin() { return const_iterator{}; } 112 113 void push_front(const T &) {} 114 void push_front(T &&) {} 115 116 template <typename... Args> 117 void emplace_front(Args &&...args){}; 118 template <typename... Args> 119 iterator emplace_after(const_iterator pos, Args &&...args){}; 120 }; 121 122 template <typename T> 123 class set { 124 public: 125 using value_type = T; 126 127 class iterator {}; 128 class const_iterator {}; 129 const_iterator begin() { return const_iterator{}; } 130 131 template <typename... Args> 132 void emplace(Args &&...args){}; 133 template <typename... Args> 134 iterator emplace_hint(const_iterator pos, Args &&...args){}; 135 }; 136 137 template <typename Key, typename T> 138 class map { 139 public: 140 using value_type = std::pair<Key, T>; 141 142 class iterator {}; 143 class const_iterator {}; 144 const_iterator begin() { return const_iterator{}; } 145 146 template <typename... Args> 147 void emplace(Args &&...args){}; 148 template <typename... Args> 149 iterator emplace_hint(const_iterator pos, Args &&...args){}; 150 }; 151 152 template <typename T> 153 class multiset { 154 public: 155 using value_type = T; 156 157 class iterator {}; 158 class const_iterator {}; 159 const_iterator begin() { return const_iterator{}; } 160 161 template <typename... Args> 162 void emplace(Args &&...args){}; 163 template <typename... Args> 164 iterator emplace_hint(const_iterator pos, Args &&...args){}; 165 }; 166 167 template <typename Key, typename T> 168 class multimap { 169 public: 170 using value_type = std::pair<Key, T>; 171 172 class iterator {}; 173 class const_iterator {}; 174 const_iterator begin() { return const_iterator{}; } 175 176 template <typename... Args> 177 void emplace(Args &&...args){}; 178 template <typename... Args> 179 iterator emplace_hint(const_iterator pos, Args &&...args){}; 180 }; 181 182 template <typename T> 183 class unordered_set { 184 public: 185 using value_type = T; 186 187 class iterator {}; 188 class const_iterator {}; 189 const_iterator begin() { return const_iterator{}; } 190 191 template <typename... Args> 192 void emplace(Args &&...args){}; 193 template <typename... Args> 194 iterator emplace_hint(const_iterator pos, Args &&...args){}; 195 }; 196 197 template <typename Key, typename T> 198 class unordered_map { 199 public: 200 using value_type = std::pair<Key, T>; 201 202 class iterator {}; 203 class const_iterator {}; 204 const_iterator begin() { return const_iterator{}; } 205 206 template <typename... Args> 207 void emplace(Args &&...args){}; 208 template <typename... Args> 209 iterator emplace_hint(const_iterator pos, Args &&...args){}; 210 }; 211 212 template <typename T> 213 class unordered_multiset { 214 public: 215 using value_type = T; 216 217 class iterator {}; 218 class const_iterator {}; 219 const_iterator begin() { return const_iterator{}; } 220 221 template <typename... Args> 222 void emplace(Args &&...args){}; 223 template <typename... Args> 224 iterator emplace_hint(const_iterator pos, Args &&...args){}; 225 }; 226 227 template <typename Key, typename T> 228 class unordered_multimap { 229 public: 230 using value_type = std::pair<Key, T>; 231 232 class iterator {}; 233 class const_iterator {}; 234 const_iterator begin() { return const_iterator{}; } 235 236 template <typename... Args> 237 void emplace(Args &&...args){}; 238 template <typename... Args> 239 iterator emplace_hint(const_iterator pos, Args &&...args){}; 240 }; 241 242 template <typename T> 243 class stack { 244 public: 245 using value_type = T; 246 247 void push(const T &) {} 248 void push(T &&) {} 249 250 template <typename... Args> 251 void emplace(Args &&...args){}; 252 }; 253 254 template <typename T> 255 class queue { 256 public: 257 using value_type = T; 258 259 void push(const T &) {} 260 void push(T &&) {} 261 262 template <typename... Args> 263 void emplace(Args &&...args){}; 264 }; 265 266 template <typename T> 267 class priority_queue { 268 public: 269 using value_type = T; 270 271 void push(const T &) {} 272 void push(T &&) {} 273 274 template <typename... Args> 275 void emplace(Args &&...args){}; 276 }; 277 278 template <typename T> 279 struct remove_reference { using type = T; }; 280 template <typename T> 281 struct remove_reference<T &> { using type = T; }; 282 template <typename T> 283 struct remove_reference<T &&> { using type = T; }; 284 285 template <typename T1, typename T2> 286 pair<typename remove_reference<T1>::type, typename remove_reference<T2>::type> 287 make_pair(T1 &&, T2 &&) { 288 return {}; 289 }; 290 291 template <typename... Ts> 292 class tuple { 293 public: 294 tuple() = default; 295 tuple(const tuple &) = default; 296 tuple(tuple &&) = default; 297 298 tuple(const Ts &...) {} 299 tuple(Ts &&...) {} 300 301 template <typename... Us> 302 tuple(const tuple<Us...> &){}; 303 template <typename... Us> 304 tuple(tuple<Us...> &&) {} 305 306 template <typename U1, typename U2> 307 tuple(const pair<U1, U2> &) { 308 static_assert(sizeof...(Ts) == 2, "Wrong tuple size"); 309 }; 310 template <typename U1, typename U2> 311 tuple(pair<U1, U2> &&) { 312 static_assert(sizeof...(Ts) == 2, "Wrong tuple size"); 313 }; 314 }; 315 316 template <typename... Ts> 317 tuple<typename remove_reference<Ts>::type...> make_tuple(Ts &&...) { 318 return {}; 319 } 320 321 template <typename T> 322 class unique_ptr { 323 public: 324 explicit unique_ptr(T *) {} 325 ~unique_ptr(); 326 }; 327 } // namespace std 328 329 namespace llvm { 330 template <typename T> 331 class LikeASmallVector { 332 public: 333 void push_back(const T &) {} 334 void push_back(T &&) {} 335 336 template <typename... Args> 337 void emplace_back(Args &&... args){}; 338 }; 339 340 } // namespace llvm 341 342 void testInts() { 343 std::vector<int> v; 344 v.push_back(42); 345 v.push_back(int(42)); 346 v.push_back(int{42}); 347 v.push_back(42.0); 348 int z; 349 v.push_back(z); 350 } 351 352 struct Something { 353 Something(int a, int b = 41) {} 354 Something() {} 355 void push_back(Something); 356 int getInt() { return 42; } 357 }; 358 359 struct Convertable { 360 operator Something() { return Something{}; } 361 }; 362 363 struct Zoz { 364 Zoz(Something, int = 42) {} 365 }; 366 367 Zoz getZoz(Something s) { return Zoz(s); } 368 369 void test_Something() { 370 std::vector<Something> v; 371 372 v.push_back(Something(1, 2)); 373 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace] 374 // CHECK-FIXES: v.emplace_back(1, 2); 375 376 v.push_back(Something{1, 2}); 377 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 378 // CHECK-FIXES: v.emplace_back(1, 2); 379 380 v.push_back(Something()); 381 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 382 // CHECK-FIXES: v.emplace_back(); 383 384 v.push_back(Something{}); 385 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 386 // CHECK-FIXES: v.emplace_back(); 387 388 Something Different; 389 v.push_back(Something(Different.getInt(), 42)); 390 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 391 // CHECK-FIXES: v.emplace_back(Different.getInt(), 42); 392 393 v.push_back(Different.getInt()); 394 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 395 // CHECK-FIXES: v.emplace_back(Different.getInt()); 396 397 v.push_back(42); 398 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 399 // CHECK-FIXES: v.emplace_back(42); 400 401 Something temporary(42, 42); 402 temporary.push_back(temporary); 403 v.push_back(temporary); 404 405 v.push_back(Convertable()); 406 v.push_back(Convertable{}); 407 Convertable s; 408 v.push_back(s); 409 } 410 411 template <typename ElemType> 412 void dependOnElem() { 413 std::vector<ElemType> v; 414 v.push_back(ElemType(42)); 415 } 416 417 template <typename ContainerType> 418 void dependOnContainer() { 419 ContainerType v; 420 v.push_back(Something(42)); 421 } 422 423 void callDependent() { 424 dependOnElem<Something>(); 425 dependOnContainer<std::vector<Something>>(); 426 } 427 428 void test2() { 429 std::vector<Zoz> v; 430 v.push_back(Zoz(Something(21, 37))); 431 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 432 // CHECK-FIXES: v.emplace_back(Something(21, 37)); 433 434 v.push_back(Zoz(Something(21, 37), 42)); 435 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 436 // CHECK-FIXES: v.emplace_back(Something(21, 37), 42); 437 438 v.push_back(getZoz(Something(1, 2))); 439 } 440 441 struct GetPair { 442 std::pair<int, long> getPair(); 443 }; 444 void testPair() { 445 std::vector<std::pair<int, int>> v; 446 v.push_back(std::pair<int, int>(1, 2)); 447 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 448 // CHECK-FIXES: v.emplace_back(1, 2); 449 450 GetPair g; 451 v.push_back(g.getPair()); 452 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 453 // CHECK-FIXES: v.emplace_back(g.getPair()); 454 455 std::vector<std::pair<Something, Zoz>> v2; 456 v2.push_back(std::pair<Something, Zoz>(Something(42, 42), Zoz(Something(21, 37)))); 457 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 458 // CHECK-FIXES: v2.emplace_back(Something(42, 42), Zoz(Something(21, 37))); 459 } 460 461 void testTuple() { 462 std::vector<std::tuple<bool, char, int>> v; 463 v.push_back(std::tuple<bool, char, int>(false, 'x', 1)); 464 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 465 // CHECK-FIXES: v.emplace_back(false, 'x', 1); 466 467 v.push_back(std::tuple<bool, char, int>{false, 'y', 2}); 468 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 469 // CHECK-FIXES: v.emplace_back(false, 'y', 2); 470 471 v.push_back({true, 'z', 3}); 472 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 473 // CHECK-FIXES: v.emplace_back(true, 'z', 3); 474 475 std::vector<std::tuple<int, bool>> x; 476 x.push_back(std::make_pair(1, false)); 477 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 478 // CHECK-FIXES: x.emplace_back(1, false); 479 480 x.push_back(std::make_pair(2LL, 1)); 481 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 482 // CHECK-FIXES: x.emplace_back(2LL, 1); 483 } 484 485 struct Base { 486 Base(int, int *, int = 42); 487 }; 488 489 struct Derived : Base { 490 Derived(int *, Something) : Base(42, nullptr) {} 491 }; 492 493 void testDerived() { 494 std::vector<Base> v; 495 v.push_back(Derived(nullptr, Something{})); 496 } 497 498 void testNewExpr() { 499 std::vector<Derived> v; 500 v.push_back(Derived(new int, Something{})); 501 } 502 503 void testSpaces() { 504 std::vector<Something> v; 505 506 // clang-format off 507 508 v.push_back(Something(1, //arg1 509 2 // arg2 510 ) // Something 511 ); 512 // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use emplace_back 513 // CHECK-FIXES: v.emplace_back(1, //arg1 514 // CHECK-FIXES: 2 // arg2 515 // CHECK-FIXES: // Something 516 // CHECK-FIXES: ); 517 518 v.push_back( Something (1, 2) ); 519 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 520 // CHECK-FIXES: v.emplace_back(1, 2 ); 521 522 v.push_back( Something {1, 2} ); 523 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 524 // CHECK-FIXES: v.emplace_back(1, 2 ); 525 526 v.push_back( Something {} ); 527 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 528 // CHECK-FIXES: v.emplace_back( ); 529 530 v.push_back( 531 Something(1, 2) ); 532 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use emplace_back 533 // CHECK-FIXES: v.emplace_back(1, 2 ); 534 535 std::vector<Base> v2; 536 v2.push_back( 537 Base(42, nullptr)); 538 // CHECK-MESSAGES: :[[@LINE-2]]:6: warning: use emplace_back 539 // CHECK-FIXES: v2.emplace_back(42, nullptr); 540 541 // clang-format on 542 } 543 544 void testPointers() { 545 std::vector<int *> v; 546 v.push_back(new int(5)); 547 548 std::vector<std::unique_ptr<int>> v2; 549 v2.push_back(std::unique_ptr<int>(new int(42))); 550 // This call can't be replaced with emplace_back. 551 // If emplacement will fail (not enough memory to add to vector) 552 // we will have leak of int because unique_ptr won't be constructed 553 // (and destructed) as in push_back case. 554 555 auto *ptr = new int; 556 v2.push_back(std::unique_ptr<int>(ptr)); 557 // Same here 558 } 559 560 void testMakePair() { 561 std::vector<std::pair<int, int>> v; 562 v.push_back(std::make_pair(1, 2)); 563 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 564 // CHECK-FIXES: v.emplace_back(1, 2); 565 566 v.push_back(std::make_pair(42LL, 13)); 567 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 568 // CHECK-FIXES: v.emplace_back(42LL, 13); 569 570 v.push_back(std::make_pair<char, char>(0, 3)); 571 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 572 // CHECK-FIXES: v.emplace_back(std::make_pair<char, char>(0, 3)); 573 // 574 // Even though the call above could be turned into v.emplace_back(0, 3), 575 // we don't eliminate the make_pair call here, because of the explicit 576 // template parameters provided. make_pair's arguments can be convertible 577 // to its explicitly provided template parameter, but not to the pair's 578 // element type. The examples below illustrate the problem. 579 struct D { 580 D(...) {} 581 operator char() const { return 0; } 582 }; 583 v.push_back(std::make_pair<D, int>(Something(), 2)); 584 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 585 // CHECK-FIXES: v.emplace_back(std::make_pair<D, int>(Something(), 2)); 586 587 struct X { 588 X(std::pair<int, int>) {} 589 }; 590 std::vector<X> x; 591 x.push_back(std::make_pair(1, 2)); 592 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 593 // CHECK-FIXES: x.emplace_back(std::make_pair(1, 2)); 594 // make_pair cannot be removed here, as X is not constructible with two ints. 595 596 struct Y { 597 Y(std::pair<int, int> &&) {} 598 }; 599 std::vector<Y> y; 600 y.push_back(std::make_pair(2, 3)); 601 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 602 // CHECK-FIXES: y.emplace_back(std::make_pair(2, 3)); 603 // make_pair cannot be removed here, as Y is not constructible with two ints. 604 } 605 606 void testMakeTuple() { 607 std::vector<std::tuple<int, bool, char>> v; 608 v.push_back(std::make_tuple(1, true, 'v')); 609 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 610 // CHECK-FIXES: v.emplace_back(1, true, 'v'); 611 612 v.push_back(std::make_tuple(2ULL, 1, 0)); 613 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 614 // CHECK-FIXES: v.emplace_back(2ULL, 1, 0); 615 616 v.push_back(std::make_tuple<long long, int, int>(3LL, 1, 0)); 617 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 618 // CHECK-FIXES: v.emplace_back(std::make_tuple<long long, int, int>(3LL, 1, 0)); 619 // make_tuple is not removed when there are explicit template 620 // arguments provided. 621 } 622 623 namespace test { 624 template <typename T> 625 struct Single { 626 Single() = default; 627 Single(const Single &) = default; 628 Single(Single &&) = default; 629 630 Single(const T &) {} 631 Single(T &&) {} 632 633 template <typename U> 634 Single(const Single<U> &) {} 635 template <typename U> 636 Single(Single<U> &&) {} 637 638 template <typename U> 639 Single(const std::tuple<U> &) {} 640 template <typename U> 641 Single(std::tuple<U> &&) {} 642 }; 643 644 template <typename T> 645 Single<typename std::remove_reference<T>::type> MakeSingle(T &&) { 646 return {}; 647 } 648 } // namespace test 649 650 void testOtherTuples() { 651 std::vector<test::Single<int>> v; 652 v.push_back(test::Single<int>(1)); 653 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 654 // CHECK-FIXES: v.emplace_back(1); 655 656 v.push_back({2}); 657 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 658 // CHECK-FIXES: v.emplace_back(2); 659 660 v.push_back(test::MakeSingle(3)); 661 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 662 // CHECK-FIXES: v.emplace_back(3); 663 664 v.push_back(test::MakeSingle<long long>(4)); 665 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 666 // CHECK-FIXES: v.emplace_back(test::MakeSingle<long long>(4)); 667 // We don't remove make functions with explicit template parameters. 668 669 v.push_back(test::MakeSingle(5LL)); 670 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 671 // CHECK-FIXES: v.emplace_back(5LL); 672 673 v.push_back(std::make_tuple(6)); 674 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 675 // CHECK-FIXES: v.emplace_back(6); 676 677 v.push_back(std::make_tuple(7LL)); 678 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 679 // CHECK-FIXES: v.emplace_back(7LL); 680 } 681 682 void testOtherContainers() { 683 std::list<Something> l; 684 l.push_back(Something(42, 41)); 685 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 686 // CHECK-FIXES: l.emplace_back(42, 41); 687 688 l.push_front(Something(42, 41)); 689 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_front 690 // CHECK-FIXES: l.emplace_front(42, 41); 691 692 std::deque<Something> d; 693 d.push_back(Something(42)); 694 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 695 // CHECK-FIXES: d.emplace_back(42); 696 697 d.push_front(Something(42)); 698 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_front 699 // CHECK-FIXES: d.emplace_front(42); 700 701 llvm::LikeASmallVector<Something> ls; 702 ls.push_back(Something(42)); 703 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 704 // CHECK-FIXES: ls.emplace_back(42); 705 706 std::stack<Something> s; 707 s.push(Something(42, 41)); 708 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace 709 // CHECK-FIXES: s.emplace(42, 41); 710 711 std::queue<Something> q; 712 q.push(Something(42, 41)); 713 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace 714 // CHECK-FIXES: q.emplace(42, 41); 715 716 std::priority_queue<Something> pq; 717 pq.push(Something(42, 41)); 718 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace 719 // CHECK-FIXES: pq.emplace(42, 41); 720 721 std::forward_list<Something> fl; 722 fl.push_front(Something(42, 41)); 723 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_front 724 // CHECK-FIXES: fl.emplace_front(42, 41); 725 } 726 727 class IntWrapper { 728 public: 729 IntWrapper(int x) : value(x) {} 730 IntWrapper operator+(const IntWrapper other) const { 731 return IntWrapper(value + other.value); 732 } 733 734 private: 735 int value; 736 }; 737 738 void testMultipleOpsInPushBack() { 739 std::vector<IntWrapper> v; 740 v.push_back(IntWrapper(42) + IntWrapper(27)); 741 } 742 743 // Macro tests. 744 #define PUSH_BACK_WHOLE(c, x) c.push_back(x) 745 #define PUSH_BACK_NAME push_back 746 #define PUSH_BACK_ARG(x) (x) 747 #define SOME_OBJ Something(10) 748 #define MILLION 3 749 #define SOME_WEIRD_PUSH(v) v.push_back(Something( 750 #define OPEN ( 751 #define CLOSE ) 752 void macroTest() { 753 std::vector<Something> v; 754 Something s; 755 756 PUSH_BACK_WHOLE(v, Something(5, 6)); 757 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use emplace_back 758 759 v.PUSH_BACK_NAME(Something(5)); 760 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 761 762 v.push_back PUSH_BACK_ARG(Something(5, 6)); 763 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 764 765 v.push_back(SOME_OBJ); 766 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 767 768 v.push_back(Something(MILLION)); 769 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 770 // CHECK-FIXES: v.emplace_back(MILLION); 771 772 // clang-format off 773 v.push_back( Something OPEN 3 CLOSE ); 774 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 775 // clang-format on 776 PUSH_BACK_WHOLE(s, Something(1)); 777 } 778 779 struct A { 780 int value1, value2; 781 }; 782 783 struct B { 784 B(A) {} 785 }; 786 787 struct C { 788 int value1, value2, value3; 789 }; 790 791 void testAggregation() { 792 // This should not be noticed or fixed; after the correction, the code won't 793 // compile. 794 795 std::vector<A> v; 796 v.push_back(A({1, 2})); 797 798 std::vector<B> vb; 799 vb.push_back(B({10, 42})); 800 } 801 802 struct Bitfield { 803 unsigned bitfield : 1; 804 unsigned notBitfield; 805 }; 806 807 void testBitfields() { 808 std::vector<Something> v; 809 Bitfield b; 810 v.push_back(Something(42, b.bitfield)); 811 v.push_back(Something(b.bitfield)); 812 813 v.push_back(Something(42, b.notBitfield)); 814 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 815 // CHECK-FIXES: v.emplace_back(42, b.notBitfield); 816 int var; 817 v.push_back(Something(42, var)); 818 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 819 // CHECK-FIXES: v.emplace_back(42, var); 820 } 821 822 class PrivateCtor { 823 PrivateCtor(int z); 824 825 public: 826 void doStuff() { 827 std::vector<PrivateCtor> v; 828 // This should not change it because emplace back doesn't have permission. 829 // Check currently doesn't support friend declarations because pretty much 830 // nobody would want to be friend with std::vector :(. 831 v.push_back(PrivateCtor(42)); 832 } 833 }; 834 835 struct WithDtor { 836 WithDtor(int) {} 837 ~WithDtor(); 838 }; 839 840 void testWithDtor() { 841 std::vector<WithDtor> v; 842 843 v.push_back(WithDtor(42)); 844 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back 845 // CHECK-FIXES: v.emplace_back(42); 846 } 847 848 void testInitializerList() { 849 std::vector<std::vector<int>> v; 850 v.push_back(std::vector<int>({1})); 851 // Test against the bug reported in PR32896. 852 853 v.push_back({{2}}); 854 855 using PairIntVector = std::pair<int, std::vector<int>>; 856 std::vector<PairIntVector> x; 857 x.push_back(PairIntVector(3, {4})); 858 x.push_back({5, {6}}); 859 } 860 861 class Foo { 862 public: 863 Foo(){}; 864 Foo(int){}; 865 Foo(int, int){}; 866 Foo(std::pair<int, int>){}; 867 868 protected: 869 Foo(char *) : Foo(){}; 870 }; 871 872 void testSomeEmplaceCases() { 873 std::vector<std::pair<char *, char *>> v1; 874 std::vector<Foo> v2; 875 std::unordered_map<int, char *> m1; 876 877 v1.emplace_back(std::make_pair("foo", "bar")); 878 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 879 // CHECK-FIXES: v1.emplace_back("foo", "bar"); 880 881 char *foo = "bar"; 882 v1.emplace_back(std::make_pair(foo, "bar")); 883 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 884 // CHECK-FIXES: v1.emplace_back(foo, "bar"); 885 886 v1.emplace(v1.begin(), std::make_pair("foo", "bar")); 887 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: unnecessary temporary object created while calling emplace 888 // CHECK-FIXES: v1.emplace(v1.begin(), "foo", "bar"); 889 890 v2.emplace_back(Foo()); 891 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 892 // CHECK-FIXES: v2.emplace_back(); 893 894 v2.emplace_back(Foo(13)); 895 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 896 // CHECK-FIXES: v2.emplace_back(13); 897 898 v2.emplace_back(Foo{13}); 899 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 900 // CHECK-FIXES: v2.emplace_back(13); 901 902 int a = 31; 903 v2.emplace_back(Foo(13, a)); 904 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 905 // CHECK-FIXES: v2.emplace_back(13, a); 906 907 v2.emplace_back(std::make_pair(3, 3)); 908 909 m1.emplace(std::make_pair(13, "foo")); 910 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: unnecessary temporary object created while calling emplace 911 // CHECK-FIXES: m1.emplace(13, "foo"); 912 913 std::vector<std::pair<int, int>> v3; 914 v3.emplace_back(std::pair<int, int>(13, 71)); 915 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 916 v3.emplace_back(std::make_pair(13, 71)); 917 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 918 919 std::vector<std::tuple<int, int, int>> v4; 920 v4.emplace_back(std::tuple<int, int, int>(13, 31, 71)); 921 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 922 v4.emplace_back(std::make_tuple(13, 31, 71)); 923 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 924 925 std::vector<test::Single<int>> v5; 926 v5.emplace_back(test::Single<int>(13)); 927 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 928 v5.emplace_back(test::MakeSingle(13)); 929 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 930 } 931 932 void testAllSTLEmplacyFunctions() { 933 std::vector<Foo> vector; 934 std::deque<Foo> deque; 935 std::forward_list<Foo> forward_list; 936 std::list<Foo> list; 937 std::set<Foo> set; 938 std::map<int, Foo> map; 939 std::multiset<Foo> multiset; 940 std::multimap<int, Foo> multimap; 941 std::unordered_set<Foo> unordered_set; 942 std::unordered_map<int, Foo> unordered_map; 943 std::unordered_multiset<Foo> unordered_multiset; 944 std::unordered_multimap<int, Foo> unordered_multimap; 945 std::stack<Foo> stack; 946 std::queue<Foo> queue; 947 std::priority_queue<Foo> priority_queue; 948 949 vector.emplace_back(Foo(13)); 950 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: unnecessary temporary object created while calling emplace_back 951 // CHECK-FIXES: vector.emplace_back(13); 952 953 vector.emplace(vector.begin(), Foo(13)); 954 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: unnecessary temporary object created while calling emplace 955 // CHECK-FIXES: vector.emplace(vector.begin(), 13); 956 957 deque.emplace(deque.begin(), Foo(13)); 958 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: unnecessary temporary object created while calling emplace 959 // CHECK-FIXES: deque.emplace(deque.begin(), 13); 960 961 deque.emplace_front(Foo(13)); 962 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: unnecessary temporary object created while calling emplace_front 963 // CHECK-FIXES: deque.emplace_front(13); 964 965 deque.emplace_back(Foo(13)); 966 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unnecessary temporary object created while calling emplace_back 967 // CHECK-FIXES: deque.emplace_back(13); 968 969 forward_list.emplace_after(forward_list.begin(), Foo(13)); 970 // CHECK-MESSAGES: :[[@LINE-1]]:52: warning: unnecessary temporary object created while calling emplace_after 971 // CHECK-FIXES: forward_list.emplace_after(forward_list.begin(), 13); 972 973 forward_list.emplace_front(Foo(13)); 974 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace_front 975 // CHECK-FIXES: forward_list.emplace_front(13); 976 977 list.emplace(list.begin(), Foo(13)); 978 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace 979 // CHECK-FIXES: list.emplace(list.begin(), 13); 980 981 list.emplace_back(Foo(13)); 982 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_back 983 // CHECK-FIXES: list.emplace_back(13); 984 985 list.emplace_front(Foo(13)); 986 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unnecessary temporary object created while calling emplace_front 987 // CHECK-FIXES: list.emplace_front(13); 988 989 set.emplace(Foo(13)); 990 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace 991 // CHECK-FIXES: set.emplace(13); 992 993 set.emplace_hint(set.begin(), Foo(13)); 994 // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: unnecessary temporary object created while calling emplace_hint 995 // CHECK-FIXES: set.emplace_hint(set.begin(), 13); 996 997 map.emplace(std::make_pair(13, Foo(13))); 998 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace 999 // CHECK-FIXES: map.emplace(13, Foo(13)); 1000 1001 map.emplace_hint(map.begin(), std::make_pair(13, Foo(13))); 1002 // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: unnecessary temporary object created while calling emplace_hint 1003 // CHECK-FIXES: map.emplace_hint(map.begin(), 13, Foo(13)); 1004 1005 multiset.emplace(Foo(13)); 1006 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace 1007 // CHECK-FIXES: multiset.emplace(13); 1008 1009 multiset.emplace_hint(multiset.begin(), Foo(13)); 1010 // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: unnecessary temporary object created while calling emplace_hint 1011 // CHECK-FIXES: multiset.emplace_hint(multiset.begin(), 13); 1012 1013 multimap.emplace(std::make_pair(13, Foo(13))); 1014 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace 1015 // CHECK-FIXES: multimap.emplace(13, Foo(13)); 1016 1017 multimap.emplace_hint(multimap.begin(), std::make_pair(13, Foo(13))); 1018 // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: unnecessary temporary object created while calling emplace_hint 1019 // CHECK-FIXES: multimap.emplace_hint(multimap.begin(), 13, Foo(13)); 1020 1021 unordered_set.emplace(Foo(13)); 1022 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unnecessary temporary object created while calling emplace 1023 // CHECK-FIXES: unordered_set.emplace(13); 1024 1025 unordered_set.emplace_hint(unordered_set.begin(), Foo(13)); 1026 // CHECK-MESSAGES: :[[@LINE-1]]:53: warning: unnecessary temporary object created while calling emplace_hint 1027 // CHECK-FIXES: unordered_set.emplace_hint(unordered_set.begin(), 13); 1028 1029 unordered_map.emplace(std::make_pair(13, Foo(13))); 1030 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unnecessary temporary object created while calling emplace 1031 // CHECK-FIXES: unordered_map.emplace(13, Foo(13)); 1032 1033 unordered_map.emplace_hint(unordered_map.begin(), std::make_pair(13, Foo(13))); 1034 // CHECK-MESSAGES: :[[@LINE-1]]:53: warning: unnecessary temporary object created while calling emplace_hint 1035 // CHECK-FIXES: unordered_map.emplace_hint(unordered_map.begin(), 13, Foo(13)); 1036 1037 unordered_multiset.emplace(Foo(13)); 1038 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace 1039 // CHECK-FIXES: unordered_multiset.emplace(13); 1040 unordered_multiset.emplace_hint(unordered_multiset.begin(), Foo(13)); 1041 // CHECK-MESSAGES: :[[@LINE-1]]:63: warning: unnecessary temporary object created while calling emplace_hint 1042 // CHECK-FIXES: unordered_multiset.emplace_hint(unordered_multiset.begin(), 13); 1043 1044 unordered_multimap.emplace(std::make_pair(13, Foo(13))); 1045 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace 1046 // CHECK-FIXES: unordered_multimap.emplace(13, Foo(13)); 1047 unordered_multimap.emplace_hint(unordered_multimap.begin(), std::make_pair(13, Foo(13))); 1048 // CHECK-MESSAGES: :[[@LINE-1]]:63: warning: unnecessary temporary object created while calling emplace_hint 1049 // CHECK-FIXES: unordered_multimap.emplace_hint(unordered_multimap.begin(), 13, Foo(13)); 1050 1051 stack.emplace(Foo(13)); 1052 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unnecessary temporary object created while calling emplace 1053 // CHECK-FIXES: stack.emplace(13); 1054 1055 queue.emplace(Foo(13)); 1056 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unnecessary temporary object created while calling emplace 1057 // CHECK-FIXES: queue.emplace(13); 1058 1059 priority_queue.emplace(Foo(13)); 1060 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: unnecessary temporary object created while calling emplace 1061 // CHECK-FIXES: priority_queue.emplace(13); 1062 } 1063 1064 void test_AliasEmplacyFunctions() { 1065 typedef std::list<Foo> L; 1066 using DQ = std::deque<Foo>; 1067 L l; 1068 l.emplace_back(Foo(3)); 1069 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unnecessary temporary object created while calling emplace_back 1070 // CHECK-FIXES: l.emplace_back(3); 1071 1072 DQ dq; 1073 dq.emplace_back(Foo(3)); 1074 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1075 // CHECK-FIXES: dq.emplace_back(3); 1076 1077 typedef std::stack<Foo> STACK; 1078 using PQ = std::priority_queue<Foo>; 1079 STACK stack; 1080 stack.emplace(Foo(3)); 1081 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unnecessary temporary object created while calling emplace 1082 // CHECK-FIXES: stack.emplace(3); 1083 1084 PQ pq; 1085 pq.emplace(Foo(3)); 1086 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: unnecessary temporary object created while calling emplace 1087 // CHECK-FIXES: pq.emplace(3); 1088 1089 typedef std::forward_list<Foo> FL; 1090 using DQ2 = std::deque<Foo>; 1091 FL fl; 1092 fl.emplace_front(Foo(3)); 1093 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_front 1094 // CHECK-FIXES: fl.emplace_front(3); 1095 1096 DQ2 dq2; 1097 dq2.emplace_front(Foo(3)); 1098 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front 1099 // CHECK-FIXES: dq2.emplace_front(3); 1100 } 1101 1102 void test_Alias() { 1103 typedef std::list<Foo> L; 1104 using DQ = std::deque<Foo>; 1105 L l; 1106 l.push_back(Foo(3)); 1107 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace] 1108 // CHECK-FIXES: l.emplace_back(3); 1109 1110 DQ dq; 1111 dq.push_back(Foo(3)); 1112 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back instead of push_back [modernize-use-emplace] 1113 // CHECK-FIXES: dq.emplace_back(3); 1114 1115 typedef std::stack<Foo> STACK; 1116 using PQ = std::priority_queue<Foo>; 1117 STACK stack; 1118 stack.push(Foo(3)); 1119 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use emplace instead of push [modernize-use-emplace] 1120 // CHECK-FIXES: stack.emplace(3); 1121 1122 PQ pq; 1123 pq.push(Foo(3)); 1124 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace instead of push [modernize-use-emplace] 1125 // CHECK-FIXES: pq.emplace(3); 1126 1127 typedef std::forward_list<Foo> FL; 1128 using DQ2 = std::deque<Foo>; 1129 FL fl; 1130 fl.push_front(Foo(3)); 1131 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_front instead of push_front [modernize-use-emplace] 1132 // CHECK-FIXES: fl.emplace_front(3); 1133 1134 DQ2 dq2; 1135 dq2.push_front(Foo(3)); 1136 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace] 1137 // CHECK-FIXES: dq2.emplace_front(3); 1138 } 1139 1140 struct Bar { 1141 public: 1142 Bar(){}; 1143 void testWithPrivateAndProtectedCtor() { 1144 std::vector<Bar> vec; 1145 1146 vec.emplace_back(Bar(13)); 1147 vec.emplace_back(Bar(13, 13)); 1148 } 1149 1150 protected: 1151 Bar(int){}; 1152 1153 private: 1154 Bar(int, int){}; 1155 }; 1156 1157 void testPossibleFalsePositives() { 1158 struct Y { 1159 Y(std::pair<int, int> &&) {} 1160 }; 1161 std::vector<Y> y; 1162 y.emplace_back(std::make_pair(2, 3)); 1163 1164 std::vector<std::pair<int, int>> v; 1165 v.emplace_back(std::make_pair<char, char>(0, 3)); 1166 1167 struct D { 1168 D(...) {} 1169 operator char() const { return 0; } 1170 }; 1171 v.emplace_back(std::make_pair<D, int>(Something(), 2)); 1172 } 1173 1174 struct InnerType { 1175 InnerType(); 1176 InnerType(char const*); 1177 }; 1178 1179 struct NonTrivialNoCtor { 1180 InnerType it; 1181 }; 1182 1183 struct NonTrivialWithVector { 1184 std::vector<int> it; 1185 }; 1186 1187 struct NonTrivialWithCtor { 1188 NonTrivialWithCtor(); 1189 NonTrivialWithCtor(std::vector<int> const&); 1190 }; 1191 1192 void testBracedInitTemporaries() { 1193 std::vector<NonTrivialNoCtor> v1; 1194 1195 v1.push_back(NonTrivialNoCtor()); 1196 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1197 // CHECK-FIXES: v1.emplace_back(); 1198 v1.push_back(NonTrivialNoCtor{}); 1199 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1200 // CHECK-FIXES: v1.emplace_back(); 1201 v1.push_back({}); 1202 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1203 // CHECK-FIXES: v1.emplace_back(); 1204 v1.push_back(NonTrivialNoCtor{InnerType{}}); 1205 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1206 // CHECK-FIXES: v1.emplace_back(); 1207 v1.push_back({InnerType{}}); 1208 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1209 // CHECK-FIXES: v1.emplace_back(); 1210 v1.push_back(NonTrivialNoCtor{InnerType()}); 1211 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1212 // CHECK-FIXES: v1.emplace_back(); 1213 v1.push_back({InnerType()}); 1214 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1215 // CHECK-FIXES: v1.emplace_back(); 1216 v1.push_back({{}}); 1217 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1218 // CHECK-FIXES: v1.emplace_back(); 1219 1220 v1.emplace_back(NonTrivialNoCtor()); 1221 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1222 // CHECK-FIXES: v1.emplace_back(); 1223 v1.emplace_back(NonTrivialNoCtor{}); 1224 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1225 // CHECK-FIXES: v1.emplace_back(); 1226 v1.emplace_back(NonTrivialNoCtor{InnerType{}}); 1227 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1228 // CHECK-FIXES: v1.emplace_back(); 1229 v1.emplace_back(NonTrivialNoCtor{{}}); 1230 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1231 // CHECK-FIXES: v1.emplace_back(); 1232 1233 // These should not be noticed or fixed; after the correction, the code won't 1234 // compile. 1235 v1.push_back(NonTrivialNoCtor{""}); 1236 v1.push_back({""}); 1237 v1.push_back(NonTrivialNoCtor{InnerType{""}}); 1238 v1.push_back({InnerType{""}}); 1239 v1.emplace_back(NonTrivialNoCtor{""}); 1240 1241 std::vector<NonTrivialWithVector> v2; 1242 1243 v2.push_back(NonTrivialWithVector()); 1244 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1245 // CHECK-FIXES: v2.emplace_back(); 1246 v2.push_back(NonTrivialWithVector{}); 1247 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1248 // CHECK-FIXES: v2.emplace_back(); 1249 v2.push_back({}); 1250 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1251 // CHECK-FIXES: v2.emplace_back(); 1252 v2.push_back(NonTrivialWithVector{std::vector<int>{}}); 1253 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1254 // CHECK-FIXES: v2.emplace_back(); 1255 v2.push_back({std::vector<int>{}}); 1256 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1257 // CHECK-FIXES: v2.emplace_back(); 1258 v2.push_back(NonTrivialWithVector{std::vector<int>()}); 1259 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1260 // CHECK-FIXES: v2.emplace_back(); 1261 v2.push_back({std::vector<int>()}); 1262 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1263 // CHECK-FIXES: v2.emplace_back(); 1264 v2.push_back({{}}); 1265 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1266 // CHECK-FIXES: v2.emplace_back(); 1267 1268 v2.emplace_back(NonTrivialWithVector()); 1269 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1270 // CHECK-FIXES: v2.emplace_back(); 1271 v2.emplace_back(NonTrivialWithVector{}); 1272 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1273 // CHECK-FIXES: v2.emplace_back(); 1274 v2.emplace_back(NonTrivialWithVector{std::vector<int>{}}); 1275 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1276 // CHECK-FIXES: v2.emplace_back(); 1277 v2.emplace_back(NonTrivialWithVector{{}}); 1278 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1279 // CHECK-FIXES: v2.emplace_back(); 1280 1281 1282 // These should not be noticed or fixed; after the correction, the code won't 1283 // compile. 1284 v2.push_back(NonTrivialWithVector{{0}}); 1285 v2.push_back({{0}}); 1286 v2.push_back(NonTrivialWithVector{std::vector<int>{0}}); 1287 v2.push_back({std::vector<int>{0}}); 1288 v2.emplace_back(NonTrivialWithVector{std::vector<int>{0}}); 1289 1290 std::vector<NonTrivialWithCtor> v3; 1291 1292 v3.push_back(NonTrivialWithCtor()); 1293 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1294 // CHECK-FIXES: v3.emplace_back(); 1295 v3.push_back(NonTrivialWithCtor{}); 1296 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1297 // CHECK-FIXES: v3.emplace_back(); 1298 v3.push_back({}); 1299 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1300 // CHECK-FIXES: v3.emplace_back(); 1301 v3.push_back(NonTrivialWithCtor{std::vector<int>()}); 1302 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1303 // CHECK-FIXES: v3.emplace_back(std::vector<int>()); 1304 v3.push_back(NonTrivialWithCtor{std::vector<int>{0}}); 1305 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1306 // CHECK-FIXES: v3.emplace_back(std::vector<int>{0}); 1307 v3.push_back(NonTrivialWithCtor{std::vector<int>{}}); 1308 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1309 // CHECK-FIXES: v3.emplace_back(std::vector<int>{}); 1310 v3.push_back({std::vector<int>{0}}); 1311 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1312 // CHECK-FIXES: v3.emplace_back(std::vector<int>{0}); 1313 v3.push_back({std::vector<int>{}}); 1314 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back 1315 // CHECK-FIXES: v3.emplace_back(std::vector<int>{}); 1316 1317 v3.emplace_back(NonTrivialWithCtor()); 1318 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1319 // CHECK-FIXES: v3.emplace_back(); 1320 v3.emplace_back(NonTrivialWithCtor{}); 1321 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1322 // CHECK-FIXES: v3.emplace_back(); 1323 v3.emplace_back(NonTrivialWithCtor{std::vector<int>{}}); 1324 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1325 // CHECK-FIXES: v3.emplace_back(std::vector<int>{}); 1326 v3.emplace_back(NonTrivialWithCtor{std::vector<int>{0}}); 1327 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back 1328 // CHECK-FIXES: v3.emplace_back(std::vector<int>{0}); 1329 1330 // These should not be noticed or fixed; after the correction, the code won't 1331 // compile. 1332 v3.push_back(NonTrivialWithCtor{{0}}); 1333 v3.push_back(NonTrivialWithCtor{{}}); 1334 v3.push_back({{0}}); 1335 v3.push_back({{}}); 1336 } 1337