forked from OSchip/llvm-project
141 lines
3.3 KiB
C++
141 lines
3.3 KiB
C++
// RUN: %check_clang_tidy %s misc-move-constructor-init %t -- -- -std=c++11 -isystem %S/Inputs/Headers
|
|
|
|
#include <s.h>
|
|
|
|
// CHECK-FIXES: #include <utility>
|
|
|
|
template <class T> struct remove_reference {typedef T type;};
|
|
template <class T> struct remove_reference<T&> {typedef T type;};
|
|
template <class T> struct remove_reference<T&&> {typedef T type;};
|
|
|
|
template <typename T>
|
|
typename remove_reference<T>::type&& move(T&& arg) {
|
|
return static_cast<typename remove_reference<T>::type&&>(arg);
|
|
}
|
|
|
|
struct C {
|
|
C() = default;
|
|
C(const C&) = default;
|
|
};
|
|
|
|
struct B {
|
|
B() {}
|
|
B(const B&) {}
|
|
B(B &&) {}
|
|
};
|
|
|
|
struct D : B {
|
|
D() : B() {}
|
|
D(const D &RHS) : B(RHS) {}
|
|
// CHECK-MESSAGES: :[[@LINE+3]]:16: warning: move constructor initializes base class by calling a copy constructor [misc-move-constructor-init]
|
|
// CHECK-MESSAGES: 23:3: note: copy constructor being called
|
|
// CHECK-MESSAGES: 24:3: note: candidate move constructor here
|
|
D(D &&RHS) : B(RHS) {}
|
|
};
|
|
|
|
struct E : B {
|
|
E() : B() {}
|
|
E(const E &RHS) : B(RHS) {}
|
|
E(E &&RHS) : B(move(RHS)) {} // ok
|
|
};
|
|
|
|
struct F {
|
|
C M;
|
|
|
|
F(F &&) : M(C()) {} // ok
|
|
};
|
|
|
|
struct G {
|
|
G() = default;
|
|
G(const G&) = default;
|
|
G(G&&) = delete;
|
|
};
|
|
|
|
struct H : G {
|
|
H() = default;
|
|
H(const H&) = default;
|
|
H(H &&RHS) : G(RHS) {} // ok
|
|
};
|
|
|
|
struct I {
|
|
I(const I &) = default; // suppresses move constructor creation
|
|
};
|
|
|
|
struct J : I {
|
|
J(J &&RHS) : I(RHS) {} // ok
|
|
};
|
|
|
|
struct K {}; // Has implicit copy and move constructors, is trivially copyable
|
|
struct L : K {
|
|
L(L &&RHS) : K(RHS) {} // ok
|
|
};
|
|
|
|
struct M {
|
|
B Mem;
|
|
// CHECK-MESSAGES: :[[@LINE+1]]:16: warning: move constructor initializes class member by calling a copy constructor [misc-move-constructor-init]
|
|
M(M &&RHS) : Mem(RHS.Mem) {}
|
|
};
|
|
|
|
struct N {
|
|
B Mem;
|
|
N(N &&RHS) : Mem(move(RHS.Mem)) {}
|
|
};
|
|
|
|
struct Movable {
|
|
Movable(Movable &&) = default;
|
|
Movable(const Movable &) = default;
|
|
Movable &operator=(const Movable &) = default;
|
|
~Movable() {}
|
|
};
|
|
|
|
struct TriviallyCopyable {
|
|
TriviallyCopyable() = default;
|
|
TriviallyCopyable(TriviallyCopyable &&) = default;
|
|
TriviallyCopyable(const TriviallyCopyable &) = default;
|
|
};
|
|
|
|
struct Positive {
|
|
Positive(Movable M) : M_(M) {}
|
|
// CHECK-MESSAGES: [[@LINE-1]]:28: warning: value argument can be moved to avoid copy [misc-move-constructor-init]
|
|
// CHECK-FIXES: Positive(Movable M) : M_(std::move(M)) {}
|
|
Movable M_;
|
|
};
|
|
|
|
struct NegativeMultipleInitializerReferences {
|
|
NegativeMultipleInitializerReferences(Movable M) : M_(M), n_(M) {}
|
|
Movable M_;
|
|
Movable n_;
|
|
};
|
|
|
|
struct NegativeReferencedInConstructorBody {
|
|
NegativeReferencedInConstructorBody(Movable M) : M_(M) { M_ = M; }
|
|
Movable M_;
|
|
};
|
|
|
|
struct NegativeParamTriviallyCopyable {
|
|
NegativeParamTriviallyCopyable(TriviallyCopyable T) : T_(T) {}
|
|
NegativeParamTriviallyCopyable(int I) : I_(I) {}
|
|
|
|
TriviallyCopyable T_;
|
|
int I_;
|
|
};
|
|
|
|
struct NegativeNotPassedByValue {
|
|
NegativeNotPassedByValue(const Movable &M) : M_(M) {}
|
|
NegativeNotPassedByValue(const Movable M) : M_(M) {}
|
|
NegativeNotPassedByValue(Movable &M) : M_(M) {}
|
|
NegativeNotPassedByValue(Movable *M) : M_(*M) {}
|
|
NegativeNotPassedByValue(const Movable *M) : M_(*M) {}
|
|
Movable M_;
|
|
};
|
|
|
|
struct Immovable {
|
|
Immovable(const Immovable &) = default;
|
|
Immovable(Immovable &&) = delete;
|
|
};
|
|
|
|
struct NegativeImmovableParameter {
|
|
NegativeImmovableParameter(Immovable I) : I_(I) {}
|
|
Immovable I_;
|
|
};
|