186 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			186 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| // Since -fdelayed-template-parsing is enabled by default on Windows (as a
 | |
| // Microsoft extension), -fno-delayed-template-parsing is used for the tests in
 | |
| // order to have the same behavior on all systems.
 | |
| //
 | |
| // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
 | |
| // RUN: clang-modernize -pass-by-value %t.cpp -- -std=c++11 -fno-delayed-template-parsing -I %S
 | |
| // RUN: FileCheck -input-file=%t.cpp %s
 | |
| //
 | |
| // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
 | |
| // RUN: clang-modernize -pass-by-value %t.cpp -- -std=c++11 -fno-delayed-template-parsing -I %S
 | |
| // RUN: FileCheck -check-prefix=SAFE_RISK -input-file=%t.cpp %s
 | |
| 
 | |
| #include "basic.h"
 | |
| // CHECK: #include <utility>
 | |
| 
 | |
| // Test that when the class declaration can't be modified we won't modify the
 | |
| // definition either.
 | |
| UnmodifiableClass::UnmodifiableClass(const Movable &M) : M(M) {}
 | |
| // CHECK: UnmodifiableClass::UnmodifiableClass(const Movable &M) : M(M) {}
 | |
| 
 | |
| struct A {
 | |
|   A(const Movable &M) : M(M) {}
 | |
|   // CHECK: A(Movable M) : M(std::move(M)) {}
 | |
|   // SAFE_RISK: A(const Movable &M) : M(M) {}
 | |
|   Movable M;
 | |
| };
 | |
| 
 | |
| // Test that we aren't modifying other things than a parameter
 | |
| Movable GlobalObj;
 | |
| struct B {
 | |
|   B(const Movable &M) : M(GlobalObj) {}
 | |
|   // CHECK: B(const Movable &M) : M(GlobalObj) {}
 | |
|   Movable M;
 | |
| };
 | |
| 
 | |
| // Test that a parameter with more than one reference to it won't be changed.
 | |
| struct C {
 | |
|   // Tests extra-reference in body
 | |
|   C(const Movable &M) : M(M) { this->i = M.a; }
 | |
|   // CHECK: C(const Movable &M) : M(M) { this->i = M.a; }
 | |
| 
 | |
|   // Tests extra-reference in init-list
 | |
|   C(const Movable &M, int) : M(M), i(M.a) {}
 | |
|   // CHECK: C(const Movable &M, int) : M(M), i(M.a) {}
 | |
|   Movable M;
 | |
|   int i;
 | |
| };
 | |
| 
 | |
| // Test that both declaration and definition are updated
 | |
| struct D {
 | |
|   D(const Movable &M);
 | |
|   // CHECK: D(Movable M);
 | |
|   Movable M;
 | |
| };
 | |
| D::D(const Movable &M) : M(M) {}
 | |
| // CHECK: D::D(Movable M) : M(std::move(M)) {}
 | |
| 
 | |
| // Test with default parameter
 | |
| struct E {
 | |
|   E(const Movable &M = Movable()) : M(M) {}
 | |
|   // CHECK: E(Movable M = Movable()) : M(std::move(M)) {}
 | |
|   Movable M;
 | |
| };
 | |
| 
 | |
| // Test with object that can't be moved
 | |
| struct F {
 | |
|   F(const NotMovable &NM) : NM(NM) {}
 | |
|   // CHECK: F(const NotMovable &NM) : NM(NM) {}
 | |
|   NotMovable NM;
 | |
| };
 | |
| 
 | |
| // Test unnamed parameter in declaration
 | |
| struct G {
 | |
|   G(const Movable &);
 | |
|   // CHECK: G(Movable );
 | |
|   Movable M;
 | |
| };
 | |
| G::G(const Movable &M) : M(M) {}
 | |
| // CHECK: G::G(Movable M) : M(std::move(M)) {}
 | |
| 
 | |
| // Test parameter with and without qualifier
 | |
| namespace ns_H {
 | |
| typedef ::Movable HMovable;
 | |
| }
 | |
| struct H {
 | |
|   H(const ns_H::HMovable &M);
 | |
|   // CHECK: H(ns_H::HMovable M);
 | |
|   ns_H::HMovable M;
 | |
| };
 | |
| using namespace ns_H;
 | |
| H::H(const HMovable &M) : M(M) {}
 | |
| // CHECK: H(HMovable M) : M(std::move(M)) {}
 | |
| 
 | |
| // Try messing up with macros
 | |
| #define MOVABLE_PARAM(Name) const Movable & Name
 | |
| // CHECK: #define MOVABLE_PARAM(Name) const Movable & Name
 | |
| struct I {
 | |
|   I(MOVABLE_PARAM(M)) : M(M) {}
 | |
|   // CHECK: I(MOVABLE_PARAM(M)) : M(M) {}
 | |
|   Movable M;
 | |
| };
 | |
| #undef MOVABLE_PARAM
 | |
| 
 | |
| // Test that templates aren't modified
 | |
| template <typename T> struct J {
 | |
|   J(const T &M) : M(M) {}
 | |
|   // CHECK: J(const T &M) : M(M) {}
 | |
|   T M;
 | |
| };
 | |
| J<Movable> j1(Movable());
 | |
| J<NotMovable> j2(NotMovable());
 | |
| 
 | |
| struct K_Movable {
 | |
|   K_Movable() = default;
 | |
|   K_Movable(const K_Movable &) = default;
 | |
|   K_Movable(K_Movable &&o) { dummy = o.dummy; }
 | |
|   int dummy;
 | |
| };
 | |
| 
 | |
| // Test with movable type with an user defined move constructor.
 | |
| struct K {
 | |
|   K(const K_Movable &M) : M(M) {}
 | |
|   // CHECK: K(K_Movable M) : M(std::move(M)) {}
 | |
|   K_Movable M;
 | |
| };
 | |
| 
 | |
| template <typename T> struct L {
 | |
|   L(const Movable &M) : M(M) {}
 | |
|   // CHECK: L(Movable M) : M(std::move(M)) {}
 | |
|   Movable M;
 | |
| };
 | |
| L<int> l(Movable());
 | |
| 
 | |
| // Test with a non-instantiated template class
 | |
| template <typename T> struct N {
 | |
|   N(const Movable &M) : M(M) {}
 | |
|   // CHECK: N(Movable M) : M(std::move(M)) {}
 | |
| 
 | |
|   Movable M;
 | |
|   T A;
 | |
| };
 | |
| 
 | |
| // Test with value parameter
 | |
| struct O {
 | |
|   O(Movable M) : M(M) {}
 | |
|   // CHECK: O(Movable M) : M(std::move(M)) {}
 | |
|   Movable M;
 | |
| };
 | |
| 
 | |
| // Test with a const-value parameter
 | |
| struct P {
 | |
|   P(const Movable M) : M(M) {}
 | |
|   // CHECK: P(const Movable M) : M(M) {}
 | |
|   Movable M;
 | |
| };
 | |
| 
 | |
| // Test with multiples parameters where some need to be changed and some don't
 | |
| // need to.
 | |
| struct Q {
 | |
|   Q(const Movable &A, const Movable &B, const Movable &C, double D)
 | |
|       : A(A), B(B), C(C), D(D) {}
 | |
|   // CHECK:      Q(const Movable &A, Movable B, Movable C, double D)
 | |
|   // CHECK-NEXT:     : A(A), B(std::move(B)), C(std::move(C)), D(D) {}
 | |
|   const Movable &A;
 | |
|   Movable B;
 | |
|   Movable C;
 | |
|   double D;
 | |
| };
 | |
| 
 | |
| // Test that value-parameters with a nested name specifier are left as-is
 | |
| namespace ns_R {
 | |
| typedef ::Movable RMovable;
 | |
| }
 | |
| struct R {
 | |
|   R(ns_R::RMovable M) : M(M) {}
 | |
|   // CHECK: R(ns_R::RMovable M) : M(std::move(M)) {}
 | |
|   ns_R::RMovable M;
 | |
| };
 | |
| 
 | |
| // Test with rvalue parameter
 | |
| struct S {
 | |
|   S(Movable &&M) : M(M) {}
 | |
|   // CHECK: S(Movable &&M) : M(M) {}
 | |
|   Movable M;
 | |
| };
 |