summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/test/clang-tidy/readability-deleted-default.cpp
blob: bf27e00135958f398031a41edcf32464352f65cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// RUN: %check_clang_tidy %s readability-deleted-default %t -- -- -std=c++11 -fno-ms-compatibility

class NoDefault {
public:
  NoDefault() = delete;
  NoDefault(NoDefault &&Other) = delete;
  NoDefault(const NoDefault &Other) = delete;
};

class MissingEverything {
public:
  MissingEverything() = default;
  // CHECK-MESSAGES: warning: default constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is lacking a default constructor; definition can either be removed or explicitly deleted [readability-deleted-default]
  MissingEverything(MissingEverything &&Other) = default;
  // CHECK-MESSAGES: warning: move constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is neither copyable nor movable; definition can either be removed or explicitly deleted [readability-deleted-default]
  MissingEverything(const MissingEverything &Other) = default;
  // CHECK-MESSAGES: warning: copy constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is not copyable; definition can either be removed or explicitly deleted [readability-deleted-default]
  MissingEverything &operator=(MissingEverything &&Other) = default;
  // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted, probably because a base class or a non-static data member is not assignable, e.g. because the latter is marked 'const'; definition can either be removed or explicitly deleted [readability-deleted-default]
  MissingEverything &operator=(const MissingEverything &Other) = default;
  // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted, probably because a base class or a non-static data member is not assignable, e.g. because the latter is marked 'const'; definition can either be removed or explicitly deleted [readability-deleted-default]

private:
  NoDefault ND;
};

class NotAssignable {
public:
  NotAssignable(NotAssignable &&Other) = default;
  NotAssignable(const NotAssignable &Other) = default;
  NotAssignable &operator=(NotAssignable &&Other) = default;
  // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted
  NotAssignable &operator=(const NotAssignable &Other) = default;
  // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted

private:
  const int I = 0;
};

class Movable {
public:
  Movable() = default;
  Movable(Movable &&Other) = default;
  Movable(const Movable &Other) = delete;
  Movable &operator=(Movable &&Other) = default;
  Movable &operator=(const Movable &Other) = delete;
};

class NotCopyable {
public:
  NotCopyable(NotCopyable &&Other) = default;
  NotCopyable(const NotCopyable &Other) = default;
  // CHECK-MESSAGES: warning: copy constructor is explicitly defaulted but implicitly deleted
  NotCopyable &operator=(NotCopyable &&Other) = default;
  NotCopyable &operator=(const NotCopyable &Other) = default;
  // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted
private:
  Movable M;
};

template <typename T> class Templated {
public:
  // No warning here, it is a templated class.
  Templated() = default;
  Templated(Templated &&Other) = default;
  Templated(const Templated &Other) = default;
  Templated &operator=(Templated &&Other) = default;
  Templated &operator=(const Templated &Other) = default;

  class InnerTemplated {
  public:
    // This class is not in itself templated, but we still don't have warning.
    InnerTemplated() = default;
    InnerTemplated(InnerTemplated &&Other) = default;
    InnerTemplated(const InnerTemplated &Other) = default;
    InnerTemplated &operator=(InnerTemplated &&Other) = default;
    InnerTemplated &operator=(const InnerTemplated &Other) = default;

  private:
    T TVar;
  };

  class InnerNotTemplated {
  public:
    // This one could technically have warnings, but currently doesn't.
    InnerNotTemplated() = default;
    InnerNotTemplated(InnerNotTemplated &&Other) = default;
    InnerNotTemplated(const InnerNotTemplated &Other) = default;
    InnerNotTemplated &operator=(InnerNotTemplated &&Other) = default;
    InnerNotTemplated &operator=(const InnerNotTemplated &Other) = default;

  private:
    int I;
  };

private:
  const T TVar{};
};

int FunctionWithInnerClass() {
  class InnerNotAssignable {
  public:
    InnerNotAssignable &operator=(InnerNotAssignable &&Other) = default;
    // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted
  private:
    const int I = 0;
  };
  return 1;
};

template <typename T>
int TemplateFunctionWithInnerClass() {
  class InnerNotAssignable {
  public:
    InnerNotAssignable &operator=(InnerNotAssignable &&Other) = default;
  private:
    const T TVar{};
  };
  return 1;
};

void Foo() {
  Templated<const int> V1;
  Templated<int>::InnerTemplated V2;
  Templated<float>::InnerNotTemplated V3;
  TemplateFunctionWithInnerClass<int>();
}
OpenPOWER on IntegriCloud