// RUN: %check_clang_tidy %s performance-move-const-arg %t

namespace std {
template <typename>
struct remove_reference;

template <typename _Tp>
struct remove_reference {
  typedef _Tp type;
};

template <typename _Tp>
struct remove_reference<_Tp &> {
  typedef _Tp type;
};

template <typename _Tp>
struct remove_reference<_Tp &&> {
  typedef _Tp type;
};

template <typename _Tp>
constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) {
  return static_cast<typename std::remove_reference<_Tp>::type &&>(__t);
}

template <typename _Tp>
constexpr _Tp &&
forward(typename remove_reference<_Tp>::type &__t) noexcept {
  return static_cast<_Tp &&>(__t);
}

} // namespace std

class A {
public:
  A() {}
  A(const A &rhs) {}
  A(A &&rhs) {}
};

struct TriviallyCopyable {
  int i;
};

void f(TriviallyCopyable) {}

void g() {
  TriviallyCopyable obj;
  f(std::move(obj));
  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: std::move of the variable 'obj' of the trivially-copyable type 'TriviallyCopyable' has no effect; remove std::move() [performance-move-const-arg]
  // CHECK-FIXES: f(obj);
}

int f1() {
  return std::move(42);
  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the expression of the trivially-copyable type 'int' has no effect; remove std::move() [performance-move-const-arg]
  // CHECK-FIXES: return 42;
}

int f2(int x2) {
  return std::move(x2);
  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the variable 'x2' of the trivially-copyable type 'int'
  // CHECK-FIXES: return x2;
}

int *f3(int *x3) {
  return std::move(x3);
  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the variable 'x3' of the trivially-copyable type 'int *'
  // CHECK-FIXES: return x3;
}

A f4(A x4) { return std::move(x4); }

A f5(const A x5) {
  return std::move(x5);
  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the const variable 'x5' has no effect; remove std::move() or make the variable non-const [performance-move-const-arg]
  // CHECK-FIXES: return x5;
}

template <typename T>
T f6(const T x6) {
  return std::move(x6);
}

void f7() { int a = f6(10); }

#define M1(x) x
void f8() {
  const A a;
  M1(A b = std::move(a);)
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: std::move of the const variable 'a' has no effect; remove std::move() or make the variable non-const
  // CHECK-FIXES: M1(A b = a;)
}

#define M2(x) std::move(x)
int f9() { return M2(1); }

template <typename T>
T f10(const int x10) {
  return std::move(x10);
  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the const variable 'x10' of the trivially-copyable type 'const int' has no effect; remove std::move() [performance-move-const-arg]
  // CHECK-FIXES: return x10;
}
void f11() {
  f10<int>(1);
  f10<double>(1);
}

class NoMoveSemantics {
public:
  NoMoveSemantics();
  NoMoveSemantics(const NoMoveSemantics &);

  NoMoveSemantics &operator=(const NoMoveSemantics &);
};

void callByConstRef(const NoMoveSemantics &);
void callByConstRef(int i, const NoMoveSemantics &);

void moveToConstReferencePositives() {
  NoMoveSemantics obj;

  // Basic case.
  callByConstRef(std::move(obj));
  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: passing result of std::move() as
  // CHECK-FIXES: callByConstRef(obj);

  // Also works for second argument.
  callByConstRef(1, std::move(obj));
  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: passing result of std::move() as
  // CHECK-FIXES: callByConstRef(1, obj);

  // Works if std::move() applied to a temporary.
  callByConstRef(std::move(NoMoveSemantics()));
  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: passing result of std::move() as
  // CHECK-FIXES: callByConstRef(NoMoveSemantics());

  // Works if calling a copy constructor.
  NoMoveSemantics other(std::move(obj));
  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: passing result of std::move() as
  // CHECK-FIXES: NoMoveSemantics other(obj);

  // Works if calling assignment operator.
  other = std::move(obj);
  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: passing result of std::move() as
  // CHECK-FIXES: other = obj;
}

class MoveSemantics {
public:
  MoveSemantics();
  MoveSemantics(MoveSemantics &&);

  MoveSemantics &operator=(MoveSemantics &&);
};

void callByValue(MoveSemantics);

void callByRValueRef(MoveSemantics &&);

template <class T>
void templateFunction(T obj) {
  T other = std::move(obj);
}

#define M3(T, obj)            \
  do {                        \
    T other = std::move(obj); \
  } while (true)

#define CALL(func) (func)()

void moveToConstReferenceNegatives() {
  // No warning when actual move takes place.
  MoveSemantics move_semantics;
  callByValue(std::move(move_semantics));
  callByRValueRef(std::move(move_semantics));
  MoveSemantics other(std::move(move_semantics));
  other = std::move(move_semantics);

  // No warning if std::move() not used.
  NoMoveSemantics no_move_semantics;
  callByConstRef(no_move_semantics);

  // No warning if instantiating a template.
  templateFunction(no_move_semantics);

  // No warning inside of macro expansions.
  M3(NoMoveSemantics, no_move_semantics);

  // No warning inside of macro expansion, even if the macro expansion is inside
  // a lambda that is, in turn, an argument to a macro.
  CALL([no_move_semantics] { M3(NoMoveSemantics, no_move_semantics); });

  auto lambda = [] {};
  auto lambda2 = std::move(lambda);
}

class MoveOnly {
public:
  MoveOnly(const MoveOnly &other) = delete;
  MoveOnly &operator=(const MoveOnly &other) = delete;
  MoveOnly(MoveOnly &&other) = default;
  MoveOnly &operator=(MoveOnly &&other) = default;
};
template <class T>
void Q(T);
void moveOnlyNegatives(MoveOnly val) {
  Q(std::move(val));
}

void fmovable(MoveSemantics);

void lambda1() {
  auto f = [](MoveSemantics m) {
    fmovable(std::move(m));
  };
  f(MoveSemantics());
}

template<class T> struct function {};

template<typename Result, typename... Args>
class function<Result(Args...)> {
public:
  function() = default;
  void operator()(Args... args) const {
    fmovable(std::forward<Args>(args)...);
  }
};

void functionInvocation() {
  function<void(MoveSemantics)> callback;
  MoveSemantics m;
  callback(std::move(m));
}

void lambda2() {
  function<void(MoveSemantics)> callback;

  auto f = [callback = std::move(callback)](MoveSemantics m) mutable {
    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: std::move of the variable 'callback' of the trivially-copyable type 'function<void (MoveSemantics)>' has no effect; remove std::move()
    // CHECK-FIXES: auto f = [callback = callback](MoveSemantics m) mutable {
    callback(std::move(m));
  };
  f(MoveSemantics());
}
