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 struct Bar { 1065 public: 1066 Bar(){}; 1067 void testWithPrivateAndProtectedCtor() { 1068 std::vector<Bar> vec; 1069 1070 vec.emplace_back(Bar(13)); 1071 vec.emplace_back(Bar(13, 13)); 1072 } 1073 1074 protected: 1075 Bar(int){}; 1076 1077 private: 1078 Bar(int, int){}; 1079 }; 1080 1081 void testPossibleFalsePositives() { 1082 struct Y { 1083 Y(std::pair<int, int> &&) {} 1084 }; 1085 std::vector<Y> y; 1086 y.emplace_back(std::make_pair(2, 3)); 1087 1088 std::vector<std::pair<int, int>> v; 1089 v.emplace_back(std::make_pair<char, char>(0, 3)); 1090 1091 struct D { 1092 D(...) {} 1093 operator char() const { return 0; } 1094 }; 1095 v.emplace_back(std::make_pair<D, int>(Something(), 2)); 1096 } 1097