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