brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.0 KiB · cc237f4 Raw
314 lines · cpp
1// RUN: %check_clang_tidy %s modernize-pass-by-value %t -- -- -fno-delayed-template-parsing2 3namespace {4// POD types are trivially move constructible.5struct POD {6  int a, b, c;7};8 9struct Movable {10  int a, b, c;11  Movable() = default;12  Movable(const Movable &) {}13  Movable(Movable &&) {}14};15 16struct NotMovable {17  NotMovable() = default;18  NotMovable(const NotMovable &) = default;19  NotMovable(NotMovable &&) = delete;20  int a, b, c;21};22}23 24struct A {25  A(const Movable &M) : M(M) {}26  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move [modernize-pass-by-value]27  // CHECK-FIXES: A(Movable M) : M(std::move(M)) {}28  Movable M;29};30 31// Test that we aren't modifying other things than a parameter.32Movable GlobalObj;33struct B {34  B(const Movable &M) : M(GlobalObj) {}35  Movable M;36};37 38// Test that a parameter with more than one reference to it won't be changed.39struct C {40  // Tests extra-reference in body.41  C(const Movable &M) : M(M) { this->i = M.a; }42 43  // Tests extra-reference in init-list.44  C(const Movable &M, int) : M(M), i(M.a) {}45  Movable M;46  int i;47};48 49// Test that both declaration and definition are updated.50struct D {51  D(const Movable &M);52  // CHECK-FIXES: D(Movable M);53  Movable M;54};55D::D(const Movable &M) : M(M) {}56// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move57// CHECK-FIXES: D::D(Movable M) : M(std::move(M)) {}58 59// Test with default parameter.60struct E {61  E(const Movable &M = Movable()) : M(M) {}62  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move63  // CHECK-FIXES: E(Movable M = Movable()) : M(std::move(M)) {}64  Movable M;65};66 67// Test with object that can't be moved.68struct F {69  F(const NotMovable &NM) : NM(NM) {}70  NotMovable NM;71};72 73// Test unnamed parameter in declaration.74struct G {75  G(const Movable &);76  // CHECK-FIXES: G(Movable );77  Movable M;78};79G::G(const Movable &M) : M(M) {}80// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move81// CHECK-FIXES: G::G(Movable M) : M(std::move(M)) {}82 83// Test parameter with and without qualifier.84namespace ns_H {85typedef ::Movable HMovable;86}87struct H {88  H(const ns_H::HMovable &M);89  // CHECK-FIXES: H(ns_H::HMovable M);90  ns_H::HMovable M;91};92using namespace ns_H;93H::H(const HMovable &M) : M(M) {}94// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move95// CHECK-FIXES: H::H(HMovable M) : M(std::move(M)) {}96 97// Try messing up with macros.98#define MOVABLE_PARAM(Name) const Movable & Name99// CHECK-FIXES: #define MOVABLE_PARAM(Name) const Movable & Name100struct I {101  I(MOVABLE_PARAM(M)) : M(M) {}102  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move103  // CHECK-FIXES: I(MOVABLE_PARAM(M)) : M(M) {}104  Movable M;105};106#undef MOVABLE_PARAM107 108// Test that templates aren't modified.109template <typename T> struct J {110  J(const T &M) : M(M) {}111  T M;112};113J<Movable> j1(Movable());114J<NotMovable> j2(NotMovable());115 116template<class T>117struct MovableTemplateT118{119  MovableTemplateT() {}120  MovableTemplateT(const MovableTemplateT& o) { }121  MovableTemplateT(MovableTemplateT&& o) { }122};123 124template <class T>125struct J2 {126  J2(const MovableTemplateT<T>& A);127  MovableTemplateT<T> M;128};129 130template <class T>131J2<T>::J2(const MovableTemplateT<T>& A) : M(A) {}132J2<int> j3(MovableTemplateT<int>{});133 134struct K_Movable {135  K_Movable() = default;136  K_Movable(const K_Movable &) = default;137  K_Movable(K_Movable &&o) { dummy = o.dummy; }138  int dummy;139};140 141// Test with movable type with an user defined move constructor.142struct K {143  K(const K_Movable &M) : M(M) {}144  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move145  // CHECK-FIXES: K(K_Movable M) : M(std::move(M)) {}146  K_Movable M;147};148 149template <typename T> struct L {150  L(const Movable &M) : M(M) {}151  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move152  // CHECK-FIXES: L(Movable M) : M(std::move(M)) {}153  Movable M;154};155L<int> l(Movable());156 157// Test with a non-instantiated template class.158template <typename T> struct N {159  N(const Movable &M) : M(M) {}160  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move161  // CHECK-FIXES: N(Movable M) : M(std::move(M)) {}162 163  Movable M;164  T A;165};166 167// Test with value parameter.168struct O {169  O(Movable M) : M(M) {}170  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move171  // CHECK-FIXES: O(Movable M) : M(std::move(M)) {}172  Movable M;173};174 175// Test with a const-value parameter.176struct P {177  P(const Movable M) : M(M) {}178  Movable M;179};180 181// Test with multiples parameters where some need to be changed and some don't.182// need to.183struct Q {184  Q(const Movable &A, const Movable &B, const Movable &C, double D)185      : A(A), B(B), C(C), D(D) {}186  // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: pass by value and use std::move187  // CHECK-MESSAGES: :[[@LINE-3]]:41: warning: pass by value and use std::move188  // CHECK-FIXES:      Q(const Movable &A, Movable B, Movable C, double D)189  // CHECK-FIXES:     : A(A), B(std::move(B)), C(std::move(C)), D(D) {}190  const Movable &A;191  Movable B;192  Movable C;193  double D;194};195 196// Test that value-parameters with a nested name specifier are left as-is.197namespace ns_R {198typedef ::Movable RMovable;199}200struct R {201  R(ns_R::RMovable M) : M(M) {}202  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move203  // CHECK-FIXES: R(ns_R::RMovable M) : M(std::move(M)) {}204  ns_R::RMovable M;205};206 207// Test with rvalue parameter.208struct S {209  S(Movable &&M) : M(M) {}210  Movable M;211};212 213template <typename T, int N> struct array { T A[N]; };214 215// Test that types that are trivially copyable will not use std::move. This will216// cause problems with performance-move-const-arg, as it will revert it.217struct T {218  T(array<int, 10> a) : a_(a) {}219  array<int, 10> a_;220};221 222struct U {223  U(const POD &M) : M(M) {}224  POD M;225};226 227// The rewrite can't look through `typedefs` and `using`.228// Test that we don't partially rewrite one decl without rewriting the other.229using MovableConstRef = const Movable &;230struct V {231  V(MovableConstRef M);232  // CHECK-FIXES: V(MovableConstRef M);233  Movable M;234};235V::V(const Movable &M) : M(M) {}236// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move237// CHECK-FIXES: V::V(const Movable &M) : M(M) {}238 239// Test with paired lvalue/rvalue overloads.240struct W1 {241  W1(const Movable &M) : M(M) {}242  W1(Movable &&M);243  Movable M;244};245struct W2 {246  W2(const Movable &M, int) : M(M) {}247  W2(Movable &&M, int);248  Movable M;249};250struct W3 {251  W3(const W1 &, const Movable &M) : M(M) {}252  W3(W1 &&, Movable &&M);253  Movable M;254};255 256struct ProtectedMovable {257  ProtectedMovable() = default;258  ProtectedMovable(const ProtectedMovable &) {}259protected:260  ProtectedMovable(ProtectedMovable &&) {}261};262 263struct PrivateMovable {264  PrivateMovable() = default;265  PrivateMovable(const PrivateMovable &) {}266private:267  PrivateMovable(PrivateMovable &&) {}268 269  friend struct X5;270};271 272struct InheritedProtectedMovable : ProtectedMovable {273  InheritedProtectedMovable() = default;274  InheritedProtectedMovable(const InheritedProtectedMovable &) {}275  InheritedProtectedMovable(InheritedProtectedMovable &&) {}276};277 278struct InheritedPrivateMovable : PrivateMovable {279  InheritedPrivateMovable() = default;280  InheritedPrivateMovable(const InheritedPrivateMovable &) {}281  InheritedPrivateMovable(InheritedPrivateMovable &&) {}282};283 284struct X1 {285  X1(const ProtectedMovable &M) : M(M) {}286  ProtectedMovable M;287};288 289struct X2 {290  X2(const PrivateMovable &M) : M(M) {}291  PrivateMovable M;292};293 294struct X3 {295  X3(const InheritedProtectedMovable &M) : M(M) {}296  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move297  // CHECK-FIXES: X3(InheritedProtectedMovable M) : M(std::move(M)) {}298  InheritedProtectedMovable M;299};300 301struct X4 {302  X4(const InheritedPrivateMovable &M) : M(M) {}303  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move304  // CHECK-FIXES: X4(InheritedPrivateMovable M) : M(std::move(M)) {}305  InheritedPrivateMovable M;306};307 308struct X5 {309  X5(const PrivateMovable &M) : M(M) {}310  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move311  // CHECK-FIXES: X5(PrivateMovable M) : M(std::move(M)) {}312  PrivateMovable M;313};314