1436 lines
46 KiB
C++
1436 lines
46 KiB
C++
|
// RUN: %check_clang_tidy %s modernize-use-emplace %t -- \
|
||
|
// RUN: -config="{CheckOptions: \
|
||
|
// RUN: {modernize-use-emplace.ContainersWithPushBack: \
|
||
|
// RUN: '::std::vector; ::std::list; ::std::deque; llvm::LikeASmallVector', \
|
||
|
// RUN: modernize-use-emplace.TupleTypes: \
|
||
|
// RUN: '::std::pair; std::tuple; ::test::Single', \
|
||
|
// RUN: modernize-use-emplace.TupleMakeFunctions: \
|
||
|
// RUN: '::std::make_pair; ::std::make_tuple; ::test::MakeSingle'}}"
|
||
|
|
||
|
namespace std {
|
||
|
template <typename>
|
||
|
class initializer_list {
|
||
|
public:
|
||
|
initializer_list() noexcept {}
|
||
|
};
|
||
|
|
||
|
template <typename T1, typename T2>
|
||
|
class pair {
|
||
|
public:
|
||
|
pair() = default;
|
||
|
pair(const pair &) = default;
|
||
|
pair(pair &&) = default;
|
||
|
|
||
|
pair(const T1 &, const T2 &) {}
|
||
|
pair(T1 &&, T2 &&) {}
|
||
|
|
||
|
template <typename U1, typename U2>
|
||
|
pair(const pair<U1, U2> &){};
|
||
|
template <typename U1, typename U2>
|
||
|
pair(pair<U1, U2> &&){};
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
class vector {
|
||
|
public:
|
||
|
using value_type = T;
|
||
|
|
||
|
class iterator {};
|
||
|
class const_iterator {};
|
||
|
const_iterator begin() { return const_iterator{}; }
|
||
|
|
||
|
vector() = default;
|
||
|
vector(initializer_list<T>) {}
|
||
|
|
||
|
void push_back(const T &) {}
|
||
|
void push_back(T &&) {}
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace_back(Args &&... args){};
|
||
|
template <typename... Args>
|
||
|
iterator emplace(const_iterator pos, Args &&...args){};
|
||
|
~vector();
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
class list {
|
||
|
public:
|
||
|
using value_type = T;
|
||
|
|
||
|
class iterator {};
|
||
|
class const_iterator {};
|
||
|
const_iterator begin() { return const_iterator{}; }
|
||
|
|
||
|
void push_front(const T &) {}
|
||
|
void push_front(T &&) {}
|
||
|
|
||
|
void push_back(const T &) {}
|
||
|
void push_back(T &&) {}
|
||
|
|
||
|
template <typename... Args>
|
||
|
iterator emplace(const_iterator pos, Args &&...args){};
|
||
|
template <typename... Args>
|
||
|
void emplace_back(Args &&... args){};
|
||
|
template <typename... Args>
|
||
|
void emplace_front(Args &&...args){};
|
||
|
~list();
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
class deque {
|
||
|
public:
|
||
|
using value_type = T;
|
||
|
|
||
|
class iterator {};
|
||
|
class const_iterator {};
|
||
|
const_iterator begin() { return const_iterator{}; }
|
||
|
|
||
|
void push_back(const T &) {}
|
||
|
void push_back(T &&) {}
|
||
|
|
||
|
void push_front(const T &) {}
|
||
|
void push_front(T &&) {}
|
||
|
|
||
|
template <typename... Args>
|
||
|
iterator emplace(const_iterator pos, Args &&...args){};
|
||
|
template <typename... Args>
|
||
|
void emplace_back(Args &&... args){};
|
||
|
template <typename... Args>
|
||
|
void emplace_front(Args &&...args){};
|
||
|
~deque();
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
class forward_list {
|
||
|
public:
|
||
|
using value_type = T;
|
||
|
|
||
|
class iterator {};
|
||
|
class const_iterator {};
|
||
|
const_iterator begin() { return const_iterator{}; }
|
||
|
|
||
|
void push_front(const T &) {}
|
||
|
void push_front(T &&) {}
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace_front(Args &&...args){};
|
||
|
template <typename... Args>
|
||
|
iterator emplace_after(const_iterator pos, Args &&...args){};
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
class set {
|
||
|
public:
|
||
|
using value_type = T;
|
||
|
|
||
|
class iterator {};
|
||
|
class const_iterator {};
|
||
|
const_iterator begin() { return const_iterator{}; }
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace(Args &&...args){};
|
||
|
template <typename... Args>
|
||
|
iterator emplace_hint(const_iterator pos, Args &&...args){};
|
||
|
};
|
||
|
|
||
|
template <typename Key, typename T>
|
||
|
class map {
|
||
|
public:
|
||
|
using value_type = std::pair<Key, T>;
|
||
|
|
||
|
class iterator {};
|
||
|
class const_iterator {};
|
||
|
const_iterator begin() { return const_iterator{}; }
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace(Args &&...args){};
|
||
|
template <typename... Args>
|
||
|
iterator emplace_hint(const_iterator pos, Args &&...args){};
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
class multiset {
|
||
|
public:
|
||
|
using value_type = T;
|
||
|
|
||
|
class iterator {};
|
||
|
class const_iterator {};
|
||
|
const_iterator begin() { return const_iterator{}; }
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace(Args &&...args){};
|
||
|
template <typename... Args>
|
||
|
iterator emplace_hint(const_iterator pos, Args &&...args){};
|
||
|
};
|
||
|
|
||
|
template <typename Key, typename T>
|
||
|
class multimap {
|
||
|
public:
|
||
|
using value_type = std::pair<Key, T>;
|
||
|
|
||
|
class iterator {};
|
||
|
class const_iterator {};
|
||
|
const_iterator begin() { return const_iterator{}; }
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace(Args &&...args){};
|
||
|
template <typename... Args>
|
||
|
iterator emplace_hint(const_iterator pos, Args &&...args){};
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
class unordered_set {
|
||
|
public:
|
||
|
using value_type = T;
|
||
|
|
||
|
class iterator {};
|
||
|
class const_iterator {};
|
||
|
const_iterator begin() { return const_iterator{}; }
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace(Args &&...args){};
|
||
|
template <typename... Args>
|
||
|
iterator emplace_hint(const_iterator pos, Args &&...args){};
|
||
|
};
|
||
|
|
||
|
template <typename Key, typename T>
|
||
|
class unordered_map {
|
||
|
public:
|
||
|
using value_type = std::pair<Key, T>;
|
||
|
|
||
|
class iterator {};
|
||
|
class const_iterator {};
|
||
|
const_iterator begin() { return const_iterator{}; }
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace(Args &&...args){};
|
||
|
template <typename... Args>
|
||
|
iterator emplace_hint(const_iterator pos, Args &&...args){};
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
class unordered_multiset {
|
||
|
public:
|
||
|
using value_type = T;
|
||
|
|
||
|
class iterator {};
|
||
|
class const_iterator {};
|
||
|
const_iterator begin() { return const_iterator{}; }
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace(Args &&...args){};
|
||
|
template <typename... Args>
|
||
|
iterator emplace_hint(const_iterator pos, Args &&...args){};
|
||
|
};
|
||
|
|
||
|
template <typename Key, typename T>
|
||
|
class unordered_multimap {
|
||
|
public:
|
||
|
using value_type = std::pair<Key, T>;
|
||
|
|
||
|
class iterator {};
|
||
|
class const_iterator {};
|
||
|
const_iterator begin() { return const_iterator{}; }
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace(Args &&...args){};
|
||
|
template <typename... Args>
|
||
|
iterator emplace_hint(const_iterator pos, Args &&...args){};
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
class stack {
|
||
|
public:
|
||
|
using value_type = T;
|
||
|
|
||
|
void push(const T &) {}
|
||
|
void push(T &&) {}
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace(Args &&...args){};
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
class queue {
|
||
|
public:
|
||
|
using value_type = T;
|
||
|
|
||
|
void push(const T &) {}
|
||
|
void push(T &&) {}
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace(Args &&...args){};
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
class priority_queue {
|
||
|
public:
|
||
|
using value_type = T;
|
||
|
|
||
|
void push(const T &) {}
|
||
|
void push(T &&) {}
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace(Args &&...args){};
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
struct remove_reference { using type = T; };
|
||
|
template <typename T>
|
||
|
struct remove_reference<T &> { using type = T; };
|
||
|
template <typename T>
|
||
|
struct remove_reference<T &&> { using type = T; };
|
||
|
|
||
|
template <typename T1, typename T2>
|
||
|
pair<typename remove_reference<T1>::type, typename remove_reference<T2>::type>
|
||
|
make_pair(T1 &&, T2 &&) {
|
||
|
return {};
|
||
|
};
|
||
|
|
||
|
template <typename... Ts>
|
||
|
class tuple {
|
||
|
public:
|
||
|
tuple() = default;
|
||
|
tuple(const tuple &) = default;
|
||
|
tuple(tuple &&) = default;
|
||
|
|
||
|
tuple(const Ts &...) {}
|
||
|
tuple(Ts &&...) {}
|
||
|
|
||
|
template <typename... Us>
|
||
|
tuple(const tuple<Us...> &){};
|
||
|
template <typename... Us>
|
||
|
tuple(tuple<Us...> &&) {}
|
||
|
|
||
|
template <typename U1, typename U2>
|
||
|
tuple(const pair<U1, U2> &) {
|
||
|
static_assert(sizeof...(Ts) == 2, "Wrong tuple size");
|
||
|
};
|
||
|
template <typename U1, typename U2>
|
||
|
tuple(pair<U1, U2> &&) {
|
||
|
static_assert(sizeof...(Ts) == 2, "Wrong tuple size");
|
||
|
};
|
||
|
};
|
||
|
|
||
|
template <typename... Ts>
|
||
|
tuple<typename remove_reference<Ts>::type...> make_tuple(Ts &&...) {
|
||
|
return {};
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
class unique_ptr {
|
||
|
public:
|
||
|
explicit unique_ptr(T *) {}
|
||
|
~unique_ptr();
|
||
|
};
|
||
|
} // namespace std
|
||
|
|
||
|
namespace llvm {
|
||
|
template <typename T>
|
||
|
class LikeASmallVector {
|
||
|
public:
|
||
|
void push_back(const T &) {}
|
||
|
void push_back(T &&) {}
|
||
|
|
||
|
template <typename... Args>
|
||
|
void emplace_back(Args &&... args){};
|
||
|
};
|
||
|
|
||
|
} // namespace llvm
|
||
|
|
||
|
void testInts() {
|
||
|
std::vector<int> v;
|
||
|
v.push_back(42);
|
||
|
v.push_back(int(42));
|
||
|
v.push_back(int{42});
|
||
|
v.push_back(42.0);
|
||
|
int z;
|
||
|
v.push_back(z);
|
||
|
}
|
||
|
|
||
|
struct Something {
|
||
|
Something(int a, int b = 41) {}
|
||
|
Something() {}
|
||
|
void push_back(Something);
|
||
|
int getInt() { return 42; }
|
||
|
};
|
||
|
|
||
|
struct Convertable {
|
||
|
operator Something() { return Something{}; }
|
||
|
};
|
||
|
|
||
|
struct Zoz {
|
||
|
Zoz(Something, int = 42) {}
|
||
|
};
|
||
|
|
||
|
Zoz getZoz(Something s) { return Zoz(s); }
|
||
|
|
||
|
void test_Something() {
|
||
|
std::vector<Something> v;
|
||
|
|
||
|
v.push_back(Something(1, 2));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace]
|
||
|
// CHECK-FIXES: v.emplace_back(1, 2);
|
||
|
|
||
|
v.push_back(Something{1, 2});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(1, 2);
|
||
|
|
||
|
v.push_back(Something());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back();
|
||
|
|
||
|
v.push_back(Something{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back();
|
||
|
|
||
|
Something Different;
|
||
|
v.push_back(Something(Different.getInt(), 42));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(Different.getInt(), 42);
|
||
|
|
||
|
v.push_back(Different.getInt());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(Different.getInt());
|
||
|
|
||
|
v.push_back(42);
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(42);
|
||
|
|
||
|
Something temporary(42, 42);
|
||
|
temporary.push_back(temporary);
|
||
|
v.push_back(temporary);
|
||
|
|
||
|
v.push_back(Convertable());
|
||
|
v.push_back(Convertable{});
|
||
|
Convertable s;
|
||
|
v.push_back(s);
|
||
|
}
|
||
|
|
||
|
template <typename ElemType>
|
||
|
void dependOnElem() {
|
||
|
std::vector<ElemType> v;
|
||
|
v.push_back(ElemType(42));
|
||
|
}
|
||
|
|
||
|
template <typename ContainerType>
|
||
|
void dependOnContainer() {
|
||
|
ContainerType v;
|
||
|
v.push_back(Something(42));
|
||
|
}
|
||
|
|
||
|
void callDependent() {
|
||
|
dependOnElem<Something>();
|
||
|
dependOnContainer<std::vector<Something>>();
|
||
|
}
|
||
|
|
||
|
void test2() {
|
||
|
std::vector<Zoz> v;
|
||
|
v.push_back(Zoz(Something(21, 37)));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(Something(21, 37));
|
||
|
|
||
|
v.push_back(Zoz(Something(21, 37), 42));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(Something(21, 37), 42);
|
||
|
|
||
|
v.push_back(getZoz(Something(1, 2)));
|
||
|
}
|
||
|
|
||
|
struct GetPair {
|
||
|
std::pair<int, long> getPair();
|
||
|
};
|
||
|
void testPair() {
|
||
|
std::vector<std::pair<int, int>> v;
|
||
|
v.push_back(std::pair<int, int>(1, 2));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(1, 2);
|
||
|
|
||
|
GetPair g;
|
||
|
v.push_back(g.getPair());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(g.getPair());
|
||
|
|
||
|
std::vector<std::pair<Something, Zoz>> v2;
|
||
|
v2.push_back(std::pair<Something, Zoz>(Something(42, 42), Zoz(Something(21, 37))));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back(Something(42, 42), Zoz(Something(21, 37)));
|
||
|
}
|
||
|
|
||
|
void testTuple() {
|
||
|
std::vector<std::tuple<bool, char, int>> v;
|
||
|
v.push_back(std::tuple<bool, char, int>(false, 'x', 1));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(false, 'x', 1);
|
||
|
|
||
|
v.push_back(std::tuple<bool, char, int>{false, 'y', 2});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(false, 'y', 2);
|
||
|
|
||
|
v.push_back({true, 'z', 3});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(true, 'z', 3);
|
||
|
|
||
|
std::vector<std::tuple<int, bool>> x;
|
||
|
x.push_back(std::make_pair(1, false));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: x.emplace_back(1, false);
|
||
|
|
||
|
x.push_back(std::make_pair(2LL, 1));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: x.emplace_back(2LL, 1);
|
||
|
}
|
||
|
|
||
|
struct Base {
|
||
|
Base(int, int *, int = 42);
|
||
|
};
|
||
|
|
||
|
struct Derived : Base {
|
||
|
Derived(int *, Something) : Base(42, nullptr) {}
|
||
|
};
|
||
|
|
||
|
void testDerived() {
|
||
|
std::vector<Base> v;
|
||
|
v.push_back(Derived(nullptr, Something{}));
|
||
|
}
|
||
|
|
||
|
void testNewExpr() {
|
||
|
std::vector<Derived> v;
|
||
|
v.push_back(Derived(new int, Something{}));
|
||
|
}
|
||
|
|
||
|
void testSpaces() {
|
||
|
std::vector<Something> v;
|
||
|
|
||
|
// clang-format off
|
||
|
|
||
|
v.push_back(Something(1, //arg1
|
||
|
2 // arg2
|
||
|
) // Something
|
||
|
);
|
||
|
// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(1, //arg1
|
||
|
// CHECK-FIXES: 2 // arg2
|
||
|
// CHECK-FIXES: // Something
|
||
|
// CHECK-FIXES: );
|
||
|
|
||
|
v.push_back( Something (1, 2) );
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(1, 2 );
|
||
|
|
||
|
v.push_back( Something {1, 2} );
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(1, 2 );
|
||
|
|
||
|
v.push_back( Something {} );
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back( );
|
||
|
|
||
|
v.push_back(
|
||
|
Something(1, 2) );
|
||
|
// CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(1, 2 );
|
||
|
|
||
|
std::vector<Base> v2;
|
||
|
v2.push_back(
|
||
|
Base(42, nullptr));
|
||
|
// CHECK-MESSAGES: :[[@LINE-2]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back(42, nullptr);
|
||
|
|
||
|
// clang-format on
|
||
|
}
|
||
|
|
||
|
void testPointers() {
|
||
|
std::vector<int *> v;
|
||
|
v.push_back(new int(5));
|
||
|
|
||
|
std::vector<std::unique_ptr<int>> v2;
|
||
|
v2.push_back(std::unique_ptr<int>(new int(42)));
|
||
|
// This call can't be replaced with emplace_back.
|
||
|
// If emplacement will fail (not enough memory to add to vector)
|
||
|
// we will have leak of int because unique_ptr won't be constructed
|
||
|
// (and destructed) as in push_back case.
|
||
|
|
||
|
auto *ptr = new int;
|
||
|
v2.push_back(std::unique_ptr<int>(ptr));
|
||
|
// Same here
|
||
|
}
|
||
|
|
||
|
void testMakePair() {
|
||
|
std::vector<std::pair<int, int>> v;
|
||
|
v.push_back(std::make_pair(1, 2));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(1, 2);
|
||
|
|
||
|
v.push_back(std::make_pair(42LL, 13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(42LL, 13);
|
||
|
|
||
|
v.push_back(std::make_pair<char, char>(0, 3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(std::make_pair<char, char>(0, 3));
|
||
|
//
|
||
|
// Even though the call above could be turned into v.emplace_back(0, 3),
|
||
|
// we don't eliminate the make_pair call here, because of the explicit
|
||
|
// template parameters provided. make_pair's arguments can be convertible
|
||
|
// to its explicitly provided template parameter, but not to the pair's
|
||
|
// element type. The examples below illustrate the problem.
|
||
|
struct D {
|
||
|
D(...) {}
|
||
|
operator char() const { return 0; }
|
||
|
};
|
||
|
v.push_back(std::make_pair<D, int>(Something(), 2));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(std::make_pair<D, int>(Something(), 2));
|
||
|
|
||
|
struct X {
|
||
|
X(std::pair<int, int>) {}
|
||
|
};
|
||
|
std::vector<X> x;
|
||
|
x.push_back(std::make_pair(1, 2));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: x.emplace_back(std::make_pair(1, 2));
|
||
|
// make_pair cannot be removed here, as X is not constructible with two ints.
|
||
|
|
||
|
struct Y {
|
||
|
Y(std::pair<int, int> &&) {}
|
||
|
};
|
||
|
std::vector<Y> y;
|
||
|
y.push_back(std::make_pair(2, 3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: y.emplace_back(std::make_pair(2, 3));
|
||
|
// make_pair cannot be removed here, as Y is not constructible with two ints.
|
||
|
}
|
||
|
|
||
|
void testMakeTuple() {
|
||
|
std::vector<std::tuple<int, bool, char>> v;
|
||
|
v.push_back(std::make_tuple(1, true, 'v'));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(1, true, 'v');
|
||
|
|
||
|
v.push_back(std::make_tuple(2ULL, 1, 0));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(2ULL, 1, 0);
|
||
|
|
||
|
v.push_back(std::make_tuple<long long, int, int>(3LL, 1, 0));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(std::make_tuple<long long, int, int>(3LL, 1, 0));
|
||
|
// make_tuple is not removed when there are explicit template
|
||
|
// arguments provided.
|
||
|
}
|
||
|
|
||
|
namespace test {
|
||
|
template <typename T>
|
||
|
struct Single {
|
||
|
Single() = default;
|
||
|
Single(const Single &) = default;
|
||
|
Single(Single &&) = default;
|
||
|
|
||
|
Single(const T &) {}
|
||
|
Single(T &&) {}
|
||
|
|
||
|
template <typename U>
|
||
|
Single(const Single<U> &) {}
|
||
|
template <typename U>
|
||
|
Single(Single<U> &&) {}
|
||
|
|
||
|
template <typename U>
|
||
|
Single(const std::tuple<U> &) {}
|
||
|
template <typename U>
|
||
|
Single(std::tuple<U> &&) {}
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
Single<typename std::remove_reference<T>::type> MakeSingle(T &&) {
|
||
|
return {};
|
||
|
}
|
||
|
} // namespace test
|
||
|
|
||
|
void testOtherTuples() {
|
||
|
std::vector<test::Single<int>> v;
|
||
|
v.push_back(test::Single<int>(1));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(1);
|
||
|
|
||
|
v.push_back({2});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(2);
|
||
|
|
||
|
v.push_back(test::MakeSingle(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(3);
|
||
|
|
||
|
v.push_back(test::MakeSingle<long long>(4));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(test::MakeSingle<long long>(4));
|
||
|
// We don't remove make functions with explicit template parameters.
|
||
|
|
||
|
v.push_back(test::MakeSingle(5LL));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(5LL);
|
||
|
|
||
|
v.push_back(std::make_tuple(6));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(6);
|
||
|
|
||
|
v.push_back(std::make_tuple(7LL));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(7LL);
|
||
|
}
|
||
|
|
||
|
void testOtherContainers() {
|
||
|
std::list<Something> l;
|
||
|
l.push_back(Something(42, 41));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: l.emplace_back(42, 41);
|
||
|
|
||
|
l.push_front(Something(42, 41));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_front
|
||
|
// CHECK-FIXES: l.emplace_front(42, 41);
|
||
|
|
||
|
std::deque<Something> d;
|
||
|
d.push_back(Something(42));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: d.emplace_back(42);
|
||
|
|
||
|
d.push_front(Something(42));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_front
|
||
|
// CHECK-FIXES: d.emplace_front(42);
|
||
|
|
||
|
llvm::LikeASmallVector<Something> ls;
|
||
|
ls.push_back(Something(42));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: ls.emplace_back(42);
|
||
|
|
||
|
std::stack<Something> s;
|
||
|
s.push(Something(42, 41));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace
|
||
|
// CHECK-FIXES: s.emplace(42, 41);
|
||
|
|
||
|
std::queue<Something> q;
|
||
|
q.push(Something(42, 41));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace
|
||
|
// CHECK-FIXES: q.emplace(42, 41);
|
||
|
|
||
|
std::priority_queue<Something> pq;
|
||
|
pq.push(Something(42, 41));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace
|
||
|
// CHECK-FIXES: pq.emplace(42, 41);
|
||
|
|
||
|
std::forward_list<Something> fl;
|
||
|
fl.push_front(Something(42, 41));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_front
|
||
|
// CHECK-FIXES: fl.emplace_front(42, 41);
|
||
|
}
|
||
|
|
||
|
class IntWrapper {
|
||
|
public:
|
||
|
IntWrapper(int x) : value(x) {}
|
||
|
IntWrapper operator+(const IntWrapper other) const {
|
||
|
return IntWrapper(value + other.value);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
int value;
|
||
|
};
|
||
|
|
||
|
void testMultipleOpsInPushBack() {
|
||
|
std::vector<IntWrapper> v;
|
||
|
v.push_back(IntWrapper(42) + IntWrapper(27));
|
||
|
}
|
||
|
|
||
|
// Macro tests.
|
||
|
#define PUSH_BACK_WHOLE(c, x) c.push_back(x)
|
||
|
#define PUSH_BACK_NAME push_back
|
||
|
#define PUSH_BACK_ARG(x) (x)
|
||
|
#define SOME_OBJ Something(10)
|
||
|
#define MILLION 3
|
||
|
#define SOME_WEIRD_PUSH(v) v.push_back(Something(
|
||
|
#define OPEN (
|
||
|
#define CLOSE )
|
||
|
void macroTest() {
|
||
|
std::vector<Something> v;
|
||
|
Something s;
|
||
|
|
||
|
PUSH_BACK_WHOLE(v, Something(5, 6));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use emplace_back
|
||
|
|
||
|
v.PUSH_BACK_NAME(Something(5));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
|
||
|
v.push_back PUSH_BACK_ARG(Something(5, 6));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
|
||
|
v.push_back(SOME_OBJ);
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
|
||
|
v.push_back(Something(MILLION));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(MILLION);
|
||
|
|
||
|
// clang-format off
|
||
|
v.push_back( Something OPEN 3 CLOSE );
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// clang-format on
|
||
|
PUSH_BACK_WHOLE(s, Something(1));
|
||
|
}
|
||
|
|
||
|
struct A {
|
||
|
int value1, value2;
|
||
|
};
|
||
|
|
||
|
struct B {
|
||
|
B(A) {}
|
||
|
};
|
||
|
|
||
|
struct C {
|
||
|
int value1, value2, value3;
|
||
|
};
|
||
|
|
||
|
void testAggregation() {
|
||
|
// This should not be noticed or fixed; after the correction, the code won't
|
||
|
// compile.
|
||
|
|
||
|
std::vector<A> v;
|
||
|
v.push_back(A({1, 2}));
|
||
|
|
||
|
std::vector<B> vb;
|
||
|
vb.push_back(B({10, 42}));
|
||
|
}
|
||
|
|
||
|
struct Bitfield {
|
||
|
unsigned bitfield : 1;
|
||
|
unsigned notBitfield;
|
||
|
};
|
||
|
|
||
|
void testBitfields() {
|
||
|
std::vector<Something> v;
|
||
|
Bitfield b;
|
||
|
v.push_back(Something(42, b.bitfield));
|
||
|
v.push_back(Something(b.bitfield));
|
||
|
|
||
|
v.push_back(Something(42, b.notBitfield));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(42, b.notBitfield);
|
||
|
int var;
|
||
|
v.push_back(Something(42, var));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(42, var);
|
||
|
}
|
||
|
|
||
|
class PrivateCtor {
|
||
|
PrivateCtor(int z);
|
||
|
|
||
|
public:
|
||
|
void doStuff() {
|
||
|
std::vector<PrivateCtor> v;
|
||
|
// This should not change it because emplace back doesn't have permission.
|
||
|
// Check currently doesn't support friend declarations because pretty much
|
||
|
// nobody would want to be friend with std::vector :(.
|
||
|
v.push_back(PrivateCtor(42));
|
||
|
}
|
||
|
};
|
||
|
|
||
|
struct WithDtor {
|
||
|
WithDtor(int) {}
|
||
|
~WithDtor();
|
||
|
};
|
||
|
|
||
|
void testWithDtor() {
|
||
|
std::vector<WithDtor> v;
|
||
|
|
||
|
v.push_back(WithDtor(42));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
|
||
|
// CHECK-FIXES: v.emplace_back(42);
|
||
|
}
|
||
|
|
||
|
void testInitializerList() {
|
||
|
std::vector<std::vector<int>> v;
|
||
|
v.push_back(std::vector<int>({1}));
|
||
|
// Test against the bug reported in PR32896.
|
||
|
|
||
|
v.push_back({{2}});
|
||
|
|
||
|
using PairIntVector = std::pair<int, std::vector<int>>;
|
||
|
std::vector<PairIntVector> x;
|
||
|
x.push_back(PairIntVector(3, {4}));
|
||
|
x.push_back({5, {6}});
|
||
|
}
|
||
|
|
||
|
class Foo {
|
||
|
public:
|
||
|
Foo(){};
|
||
|
Foo(int){};
|
||
|
Foo(int, int){};
|
||
|
Foo(std::pair<int, int>){};
|
||
|
|
||
|
protected:
|
||
|
Foo(char *) : Foo(){};
|
||
|
};
|
||
|
|
||
|
void testSomeEmplaceCases() {
|
||
|
std::vector<std::pair<char *, char *>> v1;
|
||
|
std::vector<Foo> v2;
|
||
|
std::unordered_map<int, char *> m1;
|
||
|
|
||
|
v1.emplace_back(std::make_pair("foo", "bar"));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back("foo", "bar");
|
||
|
|
||
|
char *foo = "bar";
|
||
|
v1.emplace_back(std::make_pair(foo, "bar"));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back(foo, "bar");
|
||
|
|
||
|
v1.emplace(v1.begin(), std::make_pair("foo", "bar"));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: v1.emplace(v1.begin(), "foo", "bar");
|
||
|
|
||
|
v2.emplace_back(Foo());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
|
||
|
v2.emplace_back(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back(13);
|
||
|
|
||
|
v2.emplace_back(Foo{13});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back(13);
|
||
|
|
||
|
int a = 31;
|
||
|
v2.emplace_back(Foo(13, a));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back(13, a);
|
||
|
|
||
|
v2.emplace_back(std::make_pair(3, 3));
|
||
|
|
||
|
m1.emplace(std::make_pair(13, "foo"));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: m1.emplace(13, "foo");
|
||
|
|
||
|
std::vector<std::pair<int, int>> v3;
|
||
|
v3.emplace_back(std::pair<int, int>(13, 71));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
v3.emplace_back(std::make_pair(13, 71));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
|
||
|
std::vector<std::tuple<int, int, int>> v4;
|
||
|
v4.emplace_back(std::tuple<int, int, int>(13, 31, 71));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
v4.emplace_back(std::make_tuple(13, 31, 71));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
|
||
|
std::vector<test::Single<int>> v5;
|
||
|
v5.emplace_back(test::Single<int>(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
v5.emplace_back(test::MakeSingle(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
}
|
||
|
|
||
|
void testAllSTLEmplacyFunctions() {
|
||
|
std::vector<Foo> vector;
|
||
|
std::deque<Foo> deque;
|
||
|
std::forward_list<Foo> forward_list;
|
||
|
std::list<Foo> list;
|
||
|
std::set<Foo> set;
|
||
|
std::map<int, Foo> map;
|
||
|
std::multiset<Foo> multiset;
|
||
|
std::multimap<int, Foo> multimap;
|
||
|
std::unordered_set<Foo> unordered_set;
|
||
|
std::unordered_map<int, Foo> unordered_map;
|
||
|
std::unordered_multiset<Foo> unordered_multiset;
|
||
|
std::unordered_multimap<int, Foo> unordered_multimap;
|
||
|
std::stack<Foo> stack;
|
||
|
std::queue<Foo> queue;
|
||
|
std::priority_queue<Foo> priority_queue;
|
||
|
|
||
|
vector.emplace_back(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: vector.emplace_back(13);
|
||
|
|
||
|
vector.emplace(vector.begin(), Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: vector.emplace(vector.begin(), 13);
|
||
|
|
||
|
deque.emplace(deque.begin(), Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: deque.emplace(deque.begin(), 13);
|
||
|
|
||
|
deque.emplace_front(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: unnecessary temporary object created while calling emplace_front
|
||
|
// CHECK-FIXES: deque.emplace_front(13);
|
||
|
|
||
|
deque.emplace_back(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: deque.emplace_back(13);
|
||
|
|
||
|
forward_list.emplace_after(forward_list.begin(), Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:52: warning: unnecessary temporary object created while calling emplace_after
|
||
|
// CHECK-FIXES: forward_list.emplace_after(forward_list.begin(), 13);
|
||
|
|
||
|
forward_list.emplace_front(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace_front
|
||
|
// CHECK-FIXES: forward_list.emplace_front(13);
|
||
|
|
||
|
list.emplace(list.begin(), Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: list.emplace(list.begin(), 13);
|
||
|
|
||
|
list.emplace_back(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: list.emplace_back(13);
|
||
|
|
||
|
list.emplace_front(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unnecessary temporary object created while calling emplace_front
|
||
|
// CHECK-FIXES: list.emplace_front(13);
|
||
|
|
||
|
set.emplace(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: set.emplace(13);
|
||
|
|
||
|
set.emplace_hint(set.begin(), Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: unnecessary temporary object created while calling emplace_hint
|
||
|
// CHECK-FIXES: set.emplace_hint(set.begin(), 13);
|
||
|
|
||
|
map.emplace(std::make_pair(13, Foo(13)));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: map.emplace(13, Foo(13));
|
||
|
|
||
|
map.emplace_hint(map.begin(), std::make_pair(13, Foo(13)));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: unnecessary temporary object created while calling emplace_hint
|
||
|
// CHECK-FIXES: map.emplace_hint(map.begin(), 13, Foo(13));
|
||
|
|
||
|
multiset.emplace(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: multiset.emplace(13);
|
||
|
|
||
|
multiset.emplace_hint(multiset.begin(), Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: unnecessary temporary object created while calling emplace_hint
|
||
|
// CHECK-FIXES: multiset.emplace_hint(multiset.begin(), 13);
|
||
|
|
||
|
multimap.emplace(std::make_pair(13, Foo(13)));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: multimap.emplace(13, Foo(13));
|
||
|
|
||
|
multimap.emplace_hint(multimap.begin(), std::make_pair(13, Foo(13)));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: unnecessary temporary object created while calling emplace_hint
|
||
|
// CHECK-FIXES: multimap.emplace_hint(multimap.begin(), 13, Foo(13));
|
||
|
|
||
|
unordered_set.emplace(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: unordered_set.emplace(13);
|
||
|
|
||
|
unordered_set.emplace_hint(unordered_set.begin(), Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:53: warning: unnecessary temporary object created while calling emplace_hint
|
||
|
// CHECK-FIXES: unordered_set.emplace_hint(unordered_set.begin(), 13);
|
||
|
|
||
|
unordered_map.emplace(std::make_pair(13, Foo(13)));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: unordered_map.emplace(13, Foo(13));
|
||
|
|
||
|
unordered_map.emplace_hint(unordered_map.begin(), std::make_pair(13, Foo(13)));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:53: warning: unnecessary temporary object created while calling emplace_hint
|
||
|
// CHECK-FIXES: unordered_map.emplace_hint(unordered_map.begin(), 13, Foo(13));
|
||
|
|
||
|
unordered_multiset.emplace(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: unordered_multiset.emplace(13);
|
||
|
unordered_multiset.emplace_hint(unordered_multiset.begin(), Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:63: warning: unnecessary temporary object created while calling emplace_hint
|
||
|
// CHECK-FIXES: unordered_multiset.emplace_hint(unordered_multiset.begin(), 13);
|
||
|
|
||
|
unordered_multimap.emplace(std::make_pair(13, Foo(13)));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: unordered_multimap.emplace(13, Foo(13));
|
||
|
unordered_multimap.emplace_hint(unordered_multimap.begin(), std::make_pair(13, Foo(13)));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:63: warning: unnecessary temporary object created while calling emplace_hint
|
||
|
// CHECK-FIXES: unordered_multimap.emplace_hint(unordered_multimap.begin(), 13, Foo(13));
|
||
|
|
||
|
stack.emplace(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: stack.emplace(13);
|
||
|
|
||
|
queue.emplace(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: queue.emplace(13);
|
||
|
|
||
|
priority_queue.emplace(Foo(13));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: priority_queue.emplace(13);
|
||
|
}
|
||
|
|
||
|
void test_AliasEmplacyFunctions() {
|
||
|
typedef std::list<Foo> L;
|
||
|
using DQ = std::deque<Foo>;
|
||
|
L l;
|
||
|
l.emplace_back(Foo(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: l.emplace_back(3);
|
||
|
|
||
|
DQ dq;
|
||
|
dq.emplace_back(Foo(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: dq.emplace_back(3);
|
||
|
|
||
|
typedef std::stack<Foo> STACK;
|
||
|
using PQ = std::priority_queue<Foo>;
|
||
|
STACK stack;
|
||
|
stack.emplace(Foo(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: stack.emplace(3);
|
||
|
|
||
|
PQ pq;
|
||
|
pq.emplace(Foo(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: pq.emplace(3);
|
||
|
|
||
|
typedef std::forward_list<Foo> FL;
|
||
|
using DQ2 = std::deque<Foo>;
|
||
|
FL fl;
|
||
|
fl.emplace_front(Foo(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_front
|
||
|
// CHECK-FIXES: fl.emplace_front(3);
|
||
|
|
||
|
DQ2 dq2;
|
||
|
dq2.emplace_front(Foo(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front
|
||
|
// CHECK-FIXES: dq2.emplace_front(3);
|
||
|
}
|
||
|
|
||
|
void test_Alias() {
|
||
|
typedef std::list<Foo> L;
|
||
|
using DQ = std::deque<Foo>;
|
||
|
L l;
|
||
|
l.push_back(Foo(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace]
|
||
|
// CHECK-FIXES: l.emplace_back(3);
|
||
|
|
||
|
DQ dq;
|
||
|
dq.push_back(Foo(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back instead of push_back [modernize-use-emplace]
|
||
|
// CHECK-FIXES: dq.emplace_back(3);
|
||
|
|
||
|
typedef std::stack<Foo> STACK;
|
||
|
using PQ = std::priority_queue<Foo>;
|
||
|
STACK stack;
|
||
|
stack.push(Foo(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use emplace instead of push [modernize-use-emplace]
|
||
|
// CHECK-FIXES: stack.emplace(3);
|
||
|
|
||
|
PQ pq;
|
||
|
pq.push(Foo(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace instead of push [modernize-use-emplace]
|
||
|
// CHECK-FIXES: pq.emplace(3);
|
||
|
|
||
|
typedef std::forward_list<Foo> FL;
|
||
|
using DQ2 = std::deque<Foo>;
|
||
|
FL fl;
|
||
|
fl.push_front(Foo(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_front instead of push_front [modernize-use-emplace]
|
||
|
// CHECK-FIXES: fl.emplace_front(3);
|
||
|
|
||
|
DQ2 dq2;
|
||
|
dq2.push_front(Foo(3));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace]
|
||
|
// CHECK-FIXES: dq2.emplace_front(3);
|
||
|
}
|
||
|
|
||
|
struct Bar {
|
||
|
public:
|
||
|
Bar(){};
|
||
|
void testWithPrivateAndProtectedCtor() {
|
||
|
std::vector<Bar> vec;
|
||
|
|
||
|
vec.emplace_back(Bar(13));
|
||
|
vec.emplace_back(Bar(13, 13));
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
Bar(int){};
|
||
|
|
||
|
private:
|
||
|
Bar(int, int){};
|
||
|
};
|
||
|
|
||
|
void testPossibleFalsePositives() {
|
||
|
struct Y {
|
||
|
Y(std::pair<int, int> &&) {}
|
||
|
};
|
||
|
std::vector<Y> y;
|
||
|
y.emplace_back(std::make_pair(2, 3));
|
||
|
|
||
|
std::vector<std::pair<int, int>> v;
|
||
|
v.emplace_back(std::make_pair<char, char>(0, 3));
|
||
|
|
||
|
struct D {
|
||
|
D(...) {}
|
||
|
operator char() const { return 0; }
|
||
|
};
|
||
|
v.emplace_back(std::make_pair<D, int>(Something(), 2));
|
||
|
}
|
||
|
|
||
|
struct InnerType {
|
||
|
InnerType();
|
||
|
InnerType(char const*);
|
||
|
};
|
||
|
|
||
|
struct NonTrivialNoCtor {
|
||
|
InnerType it;
|
||
|
};
|
||
|
|
||
|
struct NonTrivialWithVector {
|
||
|
std::vector<int> it;
|
||
|
};
|
||
|
|
||
|
struct NonTrivialWithIntAndVector {
|
||
|
int x;
|
||
|
std::vector<int> it;
|
||
|
};
|
||
|
|
||
|
struct NonTrivialWithCtor {
|
||
|
NonTrivialWithCtor();
|
||
|
NonTrivialWithCtor(std::vector<int> const&);
|
||
|
};
|
||
|
|
||
|
void testBracedInitTemporaries() {
|
||
|
std::vector<NonTrivialNoCtor> v1;
|
||
|
|
||
|
v1.push_back(NonTrivialNoCtor());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back();
|
||
|
v1.push_back(NonTrivialNoCtor{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back();
|
||
|
v1.push_back({});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back();
|
||
|
v1.push_back(NonTrivialNoCtor{InnerType{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back();
|
||
|
v1.push_back({InnerType{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back();
|
||
|
v1.push_back(NonTrivialNoCtor{InnerType()});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back();
|
||
|
v1.push_back({InnerType()});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back();
|
||
|
v1.push_back({{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back();
|
||
|
|
||
|
v1.emplace_back(NonTrivialNoCtor());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back();
|
||
|
v1.emplace_back(NonTrivialNoCtor{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back();
|
||
|
v1.emplace_back(NonTrivialNoCtor{InnerType{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back();
|
||
|
v1.emplace_back(NonTrivialNoCtor{{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v1.emplace_back();
|
||
|
|
||
|
// These should not be noticed or fixed; after the correction, the code won't
|
||
|
// compile.
|
||
|
v1.push_back(NonTrivialNoCtor{""});
|
||
|
v1.push_back({""});
|
||
|
v1.push_back(NonTrivialNoCtor{InnerType{""}});
|
||
|
v1.push_back({InnerType{""}});
|
||
|
v1.emplace_back(NonTrivialNoCtor{""});
|
||
|
|
||
|
std::vector<NonTrivialWithVector> v2;
|
||
|
|
||
|
v2.push_back(NonTrivialWithVector());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
v2.push_back(NonTrivialWithVector{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
v2.push_back({});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
v2.push_back(NonTrivialWithVector{std::vector<int>{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
v2.push_back({std::vector<int>{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
v2.push_back(NonTrivialWithVector{std::vector<int>()});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
v2.push_back({std::vector<int>()});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
v2.push_back({{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
|
||
|
v2.emplace_back(NonTrivialWithVector());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
v2.emplace_back(NonTrivialWithVector{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
v2.emplace_back(NonTrivialWithVector{std::vector<int>{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
v2.emplace_back(NonTrivialWithVector{{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v2.emplace_back();
|
||
|
|
||
|
|
||
|
// These should not be noticed or fixed; after the correction, the code won't
|
||
|
// compile.
|
||
|
v2.push_back(NonTrivialWithVector{{0}});
|
||
|
v2.push_back({{0}});
|
||
|
v2.push_back(NonTrivialWithVector{std::vector<int>{0}});
|
||
|
v2.push_back({std::vector<int>{0}});
|
||
|
v2.emplace_back(NonTrivialWithVector{std::vector<int>{0}});
|
||
|
|
||
|
std::vector<NonTrivialWithCtor> v3;
|
||
|
|
||
|
v3.push_back(NonTrivialWithCtor());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v3.emplace_back();
|
||
|
v3.push_back(NonTrivialWithCtor{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v3.emplace_back();
|
||
|
v3.push_back({});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v3.emplace_back();
|
||
|
v3.push_back(NonTrivialWithCtor{std::vector<int>()});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v3.emplace_back(std::vector<int>());
|
||
|
v3.push_back(NonTrivialWithCtor{std::vector<int>{0}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v3.emplace_back(std::vector<int>{0});
|
||
|
v3.push_back(NonTrivialWithCtor{std::vector<int>{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v3.emplace_back(std::vector<int>{});
|
||
|
v3.push_back({std::vector<int>{0}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v3.emplace_back(std::vector<int>{0});
|
||
|
v3.push_back({std::vector<int>{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
|
||
|
// CHECK-FIXES: v3.emplace_back(std::vector<int>{});
|
||
|
|
||
|
v3.emplace_back(NonTrivialWithCtor());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v3.emplace_back();
|
||
|
v3.emplace_back(NonTrivialWithCtor{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v3.emplace_back();
|
||
|
v3.emplace_back(NonTrivialWithCtor{std::vector<int>{}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v3.emplace_back(std::vector<int>{});
|
||
|
v3.emplace_back(NonTrivialWithCtor{std::vector<int>{0}});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: v3.emplace_back(std::vector<int>{0});
|
||
|
|
||
|
// These should not be noticed or fixed; after the correction, the code won't
|
||
|
// compile.
|
||
|
v3.push_back(NonTrivialWithCtor{{0}});
|
||
|
v3.push_back(NonTrivialWithCtor{{}});
|
||
|
v3.push_back({{0}});
|
||
|
v3.push_back({{}});
|
||
|
|
||
|
std::vector<NonTrivialWithIntAndVector> v4;
|
||
|
|
||
|
// These should not be noticed or fixed; after the correction, the code won't
|
||
|
// compile.
|
||
|
v4.push_back(NonTrivialWithIntAndVector{1, {}});
|
||
|
v4.push_back(NonTrivialWithIntAndVector{});
|
||
|
v4.push_back({});
|
||
|
}
|
||
|
|
||
|
void testWithPointerTypes() {
|
||
|
std::list<Something> l;
|
||
|
std::list<Something>* lp = &l;
|
||
|
std::stack<Something> s;
|
||
|
std::stack<Something>* sp;
|
||
|
|
||
|
lp->push_back(Something(1, 2));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_back instead of push_back [modernize-use-emplace]
|
||
|
// CHECK-FIXES: lp->emplace_back(1, 2);
|
||
|
lp->push_front(Something(1, 2));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace]
|
||
|
// CHECK-FIXES: lp->emplace_front(1, 2);
|
||
|
sp->push(Something(1, 2));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace instead of push [modernize-use-emplace]
|
||
|
// CHECK-FIXES: sp->emplace(1, 2);
|
||
|
|
||
|
lp->push_back(Something{1, 2});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_back instead of push_back [modernize-use-emplace]
|
||
|
// CHECK-FIXES: lp->emplace_back(1, 2);
|
||
|
lp->push_front(Something{1, 2});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace]
|
||
|
// CHECK-FIXES: lp->emplace_front(1, 2);
|
||
|
sp->push(Something{1, 2});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace instead of push [modernize-use-emplace]
|
||
|
// CHECK-FIXES: sp->emplace(1, 2);
|
||
|
|
||
|
lp->push_back(Something());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_back instead of push_back [modernize-use-emplace]
|
||
|
// CHECK-FIXES: lp->emplace_back();
|
||
|
lp->push_front(Something());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace]
|
||
|
// CHECK-FIXES: lp->emplace_front();
|
||
|
sp->push(Something());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace instead of push [modernize-use-emplace]
|
||
|
// CHECK-FIXES: sp->emplace();
|
||
|
|
||
|
lp->push_back(Something{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_back instead of push_back [modernize-use-emplace]
|
||
|
// CHECK-FIXES: lp->emplace_back();
|
||
|
lp->push_front(Something{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace_front instead of push_front [modernize-use-emplace]
|
||
|
// CHECK-FIXES: lp->emplace_front();
|
||
|
sp->push(Something{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use emplace instead of push [modernize-use-emplace]
|
||
|
// CHECK-FIXES: sp->emplace();
|
||
|
|
||
|
lp->emplace_back(Something(1, 2));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: lp->emplace_back(1, 2);
|
||
|
lp->emplace_front(Something(1, 2));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front
|
||
|
// CHECK-FIXES: lp->emplace_front(1, 2);
|
||
|
sp->emplace(Something(1, 2));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: sp->emplace(1, 2);
|
||
|
|
||
|
lp->emplace_back(Something{1, 2});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: lp->emplace_back(1, 2);
|
||
|
lp->emplace_front(Something{1, 2});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front
|
||
|
// CHECK-FIXES: lp->emplace_front(1, 2);
|
||
|
sp->emplace(Something{1, 2});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: sp->emplace(1, 2);
|
||
|
|
||
|
lp->emplace_back(Something());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: lp->emplace_back();
|
||
|
lp->emplace_front(Something());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front
|
||
|
// CHECK-FIXES: lp->emplace_front();
|
||
|
sp->emplace(Something());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: sp->emplace();
|
||
|
|
||
|
lp->emplace_back(Something{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: unnecessary temporary object created while calling emplace_back
|
||
|
// CHECK-FIXES: lp->emplace_back();
|
||
|
lp->emplace_front(Something{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: unnecessary temporary object created while calling emplace_front
|
||
|
// CHECK-FIXES: lp->emplace_front();
|
||
|
sp->emplace(Something{});
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: unnecessary temporary object created while calling emplace
|
||
|
// CHECK-FIXES: sp->emplace();
|
||
|
}
|