// + match for emplace calls that should be replaced with insertion
auto CallPushBack = cxxMemberCallExpr(
hasDeclaration(functionDecl(hasName("push_back"))),
- on(hasType(cxxRecordDecl(hasAnyName(ContainersWithPushBack)))));
+ on(hasType(hasCanonicalType(
+ hasDeclaration(cxxRecordDecl(hasAnyName(ContainersWithPushBack)))))));
- auto CallPush = cxxMemberCallExpr(
- hasDeclaration(functionDecl(hasName("push"))),
- on(hasType(cxxRecordDecl(hasAnyName(ContainersWithPush)))));
+ auto CallPush =
+ cxxMemberCallExpr(hasDeclaration(functionDecl(hasName("push"))),
+ on(hasType(hasCanonicalType(hasDeclaration(
+ cxxRecordDecl(hasAnyName(ContainersWithPush)))))));
auto CallPushFront = cxxMemberCallExpr(
hasDeclaration(functionDecl(hasName("push_front"))),
- on(hasType(cxxRecordDecl(hasAnyName(ContainersWithPushFront)))));
+ on(hasType(hasCanonicalType(hasDeclaration(
+ cxxRecordDecl(hasAnyName(ContainersWithPushFront)))))));
auto CallEmplacy = cxxMemberCallExpr(
hasDeclaration(
functionDecl(hasAnyNameIgnoringTemplates(EmplacyFunctions))),
- on(hasType(cxxRecordDecl(has(typedefNameDecl(
+ on(hasType(hasCanonicalType(hasDeclaration(has(typedefNameDecl(
hasName("value_type"), hasType(type(hasUnqualifiedDesugaredType(
- recordType().bind("value_type"))))))))));
+ recordType().bind("value_type")))))))))));
// We can't replace push_backs of smart pointer because
// if emplacement fails (f.e. bad_alloc in vector) we will have leak of
<clang-tidy/checks/cppcoreguidelines/pro-type-member-init>` when warnings
would be emitted for uninitialized members of an anonymous union despite
there being an initializer for one of the other members.
-
+
- Improved `modernize-use-emplace <clang-tidy/checks/modernize/use-emplace.html>`_ check.
The check now supports detecting inefficient invocations of ``push`` and
``push_front`` on STL-style containers and replacing them with ``emplace``
or ``emplace_front``.
+ The check now supports detecting alias cases of ``push_back`` ``push`` and
+ ``push_front`` on STL-style containers and replacing them with ``emplace_back``,
+ ``emplace`` or ``emplace_front``.
+
- Improved `modernize-use-equals-default <clang-tidy/checks/modernize/use-equals-default.html>`_ check.
The check now skips unions since in this case a default constructor with empty body
// 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(){};