19ae5896dSCarlos Galvez // RUN: %check_clang_tidy %s cppcoreguidelines-avoid-const-or-ref-data-members %t
29ae5896dSCarlos Galvez namespace std {
39ae5896dSCarlos Galvez template <typename T>
49ae5896dSCarlos Galvez struct unique_ptr {};
59ae5896dSCarlos Galvez 
69ae5896dSCarlos Galvez template <typename T>
79ae5896dSCarlos Galvez struct shared_ptr {};
89ae5896dSCarlos Galvez } // namespace std
99ae5896dSCarlos Galvez 
109ae5896dSCarlos Galvez namespace gsl {
119ae5896dSCarlos Galvez template <typename T>
129ae5896dSCarlos Galvez struct not_null {};
139ae5896dSCarlos Galvez } // namespace gsl
149ae5896dSCarlos Galvez 
159ae5896dSCarlos Galvez struct Ok {
169ae5896dSCarlos Galvez   int i;
179ae5896dSCarlos Galvez   int *p;
189ae5896dSCarlos Galvez   const int *pc;
199ae5896dSCarlos Galvez   std::unique_ptr<int> up;
209ae5896dSCarlos Galvez   std::shared_ptr<int> sp;
215431a31fSRafael Stahl   gsl::not_null<int*> n;
229ae5896dSCarlos Galvez };
239ae5896dSCarlos Galvez 
249ae5896dSCarlos Galvez struct ConstMember {
259ae5896dSCarlos Galvez   const int c;
269ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: member 'c' of type 'const int' is const qualified [cppcoreguidelines-avoid-const-or-ref-data-members]
279ae5896dSCarlos Galvez };
289ae5896dSCarlos Galvez 
299ae5896dSCarlos Galvez struct LvalueRefMember {
309ae5896dSCarlos Galvez   int &lr;
319ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'lr' of type 'int &' is a reference
329ae5896dSCarlos Galvez };
339ae5896dSCarlos Galvez 
349ae5896dSCarlos Galvez struct ConstRefMember {
359ae5896dSCarlos Galvez   const int &cr;
369ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: member 'cr' of type 'const int &' is a reference
379ae5896dSCarlos Galvez };
389ae5896dSCarlos Galvez 
399ae5896dSCarlos Galvez struct RvalueRefMember {
409ae5896dSCarlos Galvez   int &&rr;
419ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: member 'rr' of type 'int &&' is a reference
429ae5896dSCarlos Galvez };
439ae5896dSCarlos Galvez 
449ae5896dSCarlos Galvez struct ConstAndRefMembers {
459ae5896dSCarlos Galvez   const int c;
469ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: member 'c' of type 'const int' is const qualified
479ae5896dSCarlos Galvez   int &lr;
489ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'lr' of type 'int &' is a reference
499ae5896dSCarlos Galvez   const int &cr;
509ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: member 'cr' of type 'const int &' is a reference
519ae5896dSCarlos Galvez   int &&rr;
529ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: member 'rr' of type 'int &&' is a reference
539ae5896dSCarlos Galvez };
549ae5896dSCarlos Galvez 
559ae5896dSCarlos Galvez struct Foo {};
569ae5896dSCarlos Galvez 
579ae5896dSCarlos Galvez struct Ok2 {
589ae5896dSCarlos Galvez   Foo i;
599ae5896dSCarlos Galvez   Foo *p;
609ae5896dSCarlos Galvez   const Foo *pc;
619ae5896dSCarlos Galvez   std::unique_ptr<Foo> up;
629ae5896dSCarlos Galvez   std::shared_ptr<Foo> sp;
635431a31fSRafael Stahl   gsl::not_null<Foo*> n;
649ae5896dSCarlos Galvez };
659ae5896dSCarlos Galvez 
669ae5896dSCarlos Galvez struct ConstMember2 {
679ae5896dSCarlos Galvez   const Foo c;
689ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: member 'c' of type 'const Foo' is const qualified
699ae5896dSCarlos Galvez };
709ae5896dSCarlos Galvez 
719ae5896dSCarlos Galvez struct LvalueRefMember2 {
729ae5896dSCarlos Galvez   Foo &lr;
739ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'lr' of type 'Foo &' is a reference
749ae5896dSCarlos Galvez };
759ae5896dSCarlos Galvez 
769ae5896dSCarlos Galvez struct ConstRefMember2 {
779ae5896dSCarlos Galvez   const Foo &cr;
789ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: member 'cr' of type 'const Foo &' is a reference
799ae5896dSCarlos Galvez };
809ae5896dSCarlos Galvez 
819ae5896dSCarlos Galvez struct RvalueRefMember2 {
829ae5896dSCarlos Galvez   Foo &&rr;
839ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: member 'rr' of type 'Foo &&' is a reference
849ae5896dSCarlos Galvez };
859ae5896dSCarlos Galvez 
869ae5896dSCarlos Galvez struct ConstAndRefMembers2 {
879ae5896dSCarlos Galvez   const Foo c;
889ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: member 'c' of type 'const Foo' is const qualified
899ae5896dSCarlos Galvez   Foo &lr;
909ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'lr' of type 'Foo &' is a reference
919ae5896dSCarlos Galvez   const Foo &cr;
929ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: member 'cr' of type 'const Foo &' is a reference
939ae5896dSCarlos Galvez   Foo &&rr;
949ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: member 'rr' of type 'Foo &&' is a reference
959ae5896dSCarlos Galvez };
969ae5896dSCarlos Galvez 
979ae5896dSCarlos Galvez using ConstType = const int;
989ae5896dSCarlos Galvez using RefType = int &;
999ae5896dSCarlos Galvez using ConstRefType = const int &;
1009ae5896dSCarlos Galvez using RefRefType = int &&;
1019ae5896dSCarlos Galvez 
1029ae5896dSCarlos Galvez struct WithAlias {
1039ae5896dSCarlos Galvez   ConstType c;
1049ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: member 'c' of type 'ConstType' (aka 'const int') is const qualified
1059ae5896dSCarlos Galvez   RefType lr;
1069ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: member 'lr' of type 'RefType' (aka 'int &') is a reference
1079ae5896dSCarlos Galvez   ConstRefType cr;
1089ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: member 'cr' of type 'ConstRefType' (aka 'const int &') is a reference
1099ae5896dSCarlos Galvez   RefRefType rr;
1109ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: member 'rr' of type 'RefRefType' (aka 'int &&') is a reference
1119ae5896dSCarlos Galvez };
1129ae5896dSCarlos Galvez 
1139ae5896dSCarlos Galvez template <int N>
1149ae5896dSCarlos Galvez using Array = int[N];
1159ae5896dSCarlos Galvez 
1169ae5896dSCarlos Galvez struct ConstArrayMember {
1179ae5896dSCarlos Galvez   const Array<1> c;
1189ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: member 'c' of type 'const Array<1>' (aka 'const int[1]') is const qualified
1199ae5896dSCarlos Galvez };
1209ae5896dSCarlos Galvez 
1219ae5896dSCarlos Galvez struct LvalueRefArrayMember {
1229ae5896dSCarlos Galvez   Array<2> &lr;
1239ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: member 'lr' of type 'Array<2> &' (aka 'int (&)[2]') is a reference
1249ae5896dSCarlos Galvez };
1259ae5896dSCarlos Galvez 
1269ae5896dSCarlos Galvez struct ConstLvalueRefArrayMember {
1279ae5896dSCarlos Galvez   const Array<3> &cr;
1289ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: member 'cr' of type 'const Array<3> &' (aka 'const int (&)[3]') is a reference
1299ae5896dSCarlos Galvez };
1309ae5896dSCarlos Galvez 
1319ae5896dSCarlos Galvez struct RvalueRefArrayMember {
1329ae5896dSCarlos Galvez   Array<4> &&rr;
1339ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: member 'rr' of type 'Array<4> &&' (aka 'int (&&)[4]') is a reference
1349ae5896dSCarlos Galvez };
1359ae5896dSCarlos Galvez 
1369ae5896dSCarlos Galvez template <typename T>
1379ae5896dSCarlos Galvez struct TemplatedOk {
1389ae5896dSCarlos Galvez   T t;
1399ae5896dSCarlos Galvez };
1409ae5896dSCarlos Galvez 
1419ae5896dSCarlos Galvez template <typename T>
1429ae5896dSCarlos Galvez struct TemplatedConst {
1439ae5896dSCarlos Galvez   T t;
1449ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: member 't' of type 'const int' is const qualified
1459ae5896dSCarlos Galvez };
1469ae5896dSCarlos Galvez 
1479ae5896dSCarlos Galvez template <typename T>
1489ae5896dSCarlos Galvez struct TemplatedConstRef {
1499ae5896dSCarlos Galvez   T t;
1509ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: member 't' of type 'const int &' is a reference
1519ae5896dSCarlos Galvez };
1529ae5896dSCarlos Galvez 
1539ae5896dSCarlos Galvez template <typename T>
1549ae5896dSCarlos Galvez struct TemplatedRefRef {
1559ae5896dSCarlos Galvez   T t;
1569ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: member 't' of type 'int &&' is a reference
1579ae5896dSCarlos Galvez };
1589ae5896dSCarlos Galvez 
1599ae5896dSCarlos Galvez template <typename T>
1609ae5896dSCarlos Galvez struct TemplatedRef {
1619ae5896dSCarlos Galvez   T t;
1629ae5896dSCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: member 't' of type 'int &' is a reference
1639ae5896dSCarlos Galvez };
1649ae5896dSCarlos Galvez 
1659ae5896dSCarlos Galvez TemplatedOk<int> t1{};
1669ae5896dSCarlos Galvez TemplatedConst<const int> t2{123};
1679ae5896dSCarlos Galvez TemplatedConstRef<const int &> t3{123};
1689ae5896dSCarlos Galvez TemplatedRefRef<int &&> t4{123};
1699ae5896dSCarlos Galvez TemplatedRef<int &> t5{t1.t};
1703fd42130SCarlos Galvez 
1713fd42130SCarlos Galvez // Lambdas capturing const or ref members should not trigger warnings
1723fd42130SCarlos Galvez void lambdas()
1733fd42130SCarlos Galvez {
1743fd42130SCarlos Galvez   int x1{123};
1753fd42130SCarlos Galvez   const int x2{123};
1763fd42130SCarlos Galvez   const int& x3{123};
1773fd42130SCarlos Galvez   int&& x4{123};
1783fd42130SCarlos Galvez   int& x5{x1};
1793fd42130SCarlos Galvez 
1803fd42130SCarlos Galvez   auto v1 = [x1]{};
1813fd42130SCarlos Galvez   auto v2 = [x2]{};
1823fd42130SCarlos Galvez   auto v3 = [x3]{};
1833fd42130SCarlos Galvez   auto v4 = [x4]{};
1843fd42130SCarlos Galvez   auto v5 = [x5]{};
1853fd42130SCarlos Galvez 
1863fd42130SCarlos Galvez   auto r1 = [&x1]{};
1873fd42130SCarlos Galvez   auto r2 = [&x2]{};
1883fd42130SCarlos Galvez   auto r3 = [&x3]{};
1893fd42130SCarlos Galvez   auto r4 = [&x4]{};
1903fd42130SCarlos Galvez   auto r5 = [&x5]{};
1913fd42130SCarlos Galvez 
1923fd42130SCarlos Galvez   auto iv = [=]{
1933fd42130SCarlos Galvez     auto c1 = x1;
1943fd42130SCarlos Galvez     auto c2 = x2;
1953fd42130SCarlos Galvez     auto c3 = x3;
1963fd42130SCarlos Galvez     auto c4 = x4;
1973fd42130SCarlos Galvez     auto c5 = x5;
1983fd42130SCarlos Galvez   };
1993fd42130SCarlos Galvez 
2003fd42130SCarlos Galvez   auto ir = [&]{
2013fd42130SCarlos Galvez     auto c1 = x1;
2023fd42130SCarlos Galvez     auto c2 = x2;
2033fd42130SCarlos Galvez     auto c3 = x3;
2043fd42130SCarlos Galvez     auto c4 = x4;
2053fd42130SCarlos Galvez     auto c5 = x5;
2063fd42130SCarlos Galvez   };
2073fd42130SCarlos Galvez }
208b70e6e96SCarlos Galvez 
209b70e6e96SCarlos Galvez struct NonCopyableWithRef
210b70e6e96SCarlos Galvez {
211b70e6e96SCarlos Galvez   NonCopyableWithRef(NonCopyableWithRef const&) = delete;
212b70e6e96SCarlos Galvez   NonCopyableWithRef& operator=(NonCopyableWithRef const&) = delete;
213b70e6e96SCarlos Galvez   NonCopyableWithRef(NonCopyableWithRef&&) = default;
214b70e6e96SCarlos Galvez   NonCopyableWithRef& operator=(NonCopyableWithRef&&) = default;
215b70e6e96SCarlos Galvez 
216b70e6e96SCarlos Galvez   int& x;
217b70e6e96SCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'x' of type 'int &' is a reference
218b70e6e96SCarlos Galvez };
219b70e6e96SCarlos Galvez 
220b70e6e96SCarlos Galvez struct NonMovableWithRef
221b70e6e96SCarlos Galvez {
222b70e6e96SCarlos Galvez   NonMovableWithRef(NonMovableWithRef const&) = default;
223b70e6e96SCarlos Galvez   NonMovableWithRef& operator=(NonMovableWithRef const&) = default;
224b70e6e96SCarlos Galvez   NonMovableWithRef(NonMovableWithRef&&) = delete;
225b70e6e96SCarlos Galvez   NonMovableWithRef& operator=(NonMovableWithRef&&) = delete;
226b70e6e96SCarlos Galvez 
227b70e6e96SCarlos Galvez   int& x;
228b70e6e96SCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'x' of type 'int &' is a reference
229b70e6e96SCarlos Galvez };
230b70e6e96SCarlos Galvez 
231b70e6e96SCarlos Galvez struct NonCopyableNonMovableWithRef
232b70e6e96SCarlos Galvez {
233b70e6e96SCarlos Galvez   NonCopyableNonMovableWithRef(NonCopyableNonMovableWithRef const&) = delete;
234b70e6e96SCarlos Galvez   NonCopyableNonMovableWithRef(NonCopyableNonMovableWithRef&&) = delete;
235b70e6e96SCarlos Galvez   NonCopyableNonMovableWithRef& operator=(NonCopyableNonMovableWithRef const&) = delete;
236b70e6e96SCarlos Galvez   NonCopyableNonMovableWithRef& operator=(NonCopyableNonMovableWithRef&&) = delete;
237b70e6e96SCarlos Galvez 
238b70e6e96SCarlos Galvez   int& x; // OK, non copyable nor movable
239b70e6e96SCarlos Galvez };
240b70e6e96SCarlos Galvez 
241b70e6e96SCarlos Galvez struct NonCopyable
242b70e6e96SCarlos Galvez {
243b70e6e96SCarlos Galvez   NonCopyable(NonCopyable const&) = delete;
244b70e6e96SCarlos Galvez   NonCopyable& operator=(NonCopyable const&) = delete;
245b70e6e96SCarlos Galvez   NonCopyable(NonCopyable&&) = default;
246b70e6e96SCarlos Galvez   NonCopyable& operator=(NonCopyable&&) = default;
247b70e6e96SCarlos Galvez };
248b70e6e96SCarlos Galvez 
249b70e6e96SCarlos Galvez struct NonMovable
250b70e6e96SCarlos Galvez {
251b70e6e96SCarlos Galvez   NonMovable(NonMovable const&) = default;
252b70e6e96SCarlos Galvez   NonMovable& operator=(NonMovable const&) = default;
253b70e6e96SCarlos Galvez   NonMovable(NonMovable&&) = delete;
254b70e6e96SCarlos Galvez   NonMovable& operator=(NonMovable&&) = delete;
255b70e6e96SCarlos Galvez };
256b70e6e96SCarlos Galvez 
257b70e6e96SCarlos Galvez struct NonCopyableNonMovable
258b70e6e96SCarlos Galvez {
259b70e6e96SCarlos Galvez   NonCopyableNonMovable(NonCopyableNonMovable const&) = delete;
260b70e6e96SCarlos Galvez   NonCopyableNonMovable(NonCopyableNonMovable&&) = delete;
261b70e6e96SCarlos Galvez   NonCopyableNonMovable& operator=(NonCopyableNonMovable const&) = delete;
262b70e6e96SCarlos Galvez   NonCopyableNonMovable& operator=(NonCopyableNonMovable&&) = delete;
263b70e6e96SCarlos Galvez };
264b70e6e96SCarlos Galvez 
265b70e6e96SCarlos Galvez // Test inheritance
266b70e6e96SCarlos Galvez struct InheritFromNonCopyable : NonCopyable
267b70e6e96SCarlos Galvez {
268b70e6e96SCarlos Galvez   int& x;
269b70e6e96SCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'x' of type 'int &' is a reference
270b70e6e96SCarlos Galvez };
271b70e6e96SCarlos Galvez 
272b70e6e96SCarlos Galvez struct InheritFromNonMovable : NonMovable
273b70e6e96SCarlos Galvez {
274b70e6e96SCarlos Galvez   int& x;
275b70e6e96SCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'x' of type 'int &' is a reference
276b70e6e96SCarlos Galvez };
277b70e6e96SCarlos Galvez 
278b70e6e96SCarlos Galvez struct InheritFromNonCopyableNonMovable : NonCopyableNonMovable
279b70e6e96SCarlos Galvez {
280b70e6e96SCarlos Galvez   int& x;  // OK, non copyable nor movable
281b70e6e96SCarlos Galvez };
282b70e6e96SCarlos Galvez 
283b70e6e96SCarlos Galvez struct InheritBothFromNonCopyableAndNonMovable : NonCopyable, NonMovable
284b70e6e96SCarlos Galvez {
285b70e6e96SCarlos Galvez   int& x;  // OK, non copyable nor movable
286b70e6e96SCarlos Galvez };
287b70e6e96SCarlos Galvez 
288*605b8dadSCongcong Cai template<class T> struct TemplateInheritFromNonCopyable : NonCopyable
289*605b8dadSCongcong Cai {
290*605b8dadSCongcong Cai   int& x;
291*605b8dadSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'x' of type 'int &' is a reference
292*605b8dadSCongcong Cai };
293*605b8dadSCongcong Cai 
294*605b8dadSCongcong Cai template<class T> struct TemplateInheritFromNonMovable : NonMovable
295*605b8dadSCongcong Cai {
296*605b8dadSCongcong Cai   int& x;
297*605b8dadSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'x' of type 'int &' is a reference
298*605b8dadSCongcong Cai };
299*605b8dadSCongcong Cai 
300*605b8dadSCongcong Cai template<class T> struct TemplateInheritFromNonCopyableNonMovable : NonCopyableNonMovable
301*605b8dadSCongcong Cai {
302*605b8dadSCongcong Cai   int& x;  // OK, non copyable nor movable
303*605b8dadSCongcong Cai };
304*605b8dadSCongcong Cai 
305*605b8dadSCongcong Cai template<class T> struct TemplateInheritBothFromNonCopyableAndNonMovable : NonCopyable, NonMovable
306*605b8dadSCongcong Cai {
307*605b8dadSCongcong Cai   int& x;  // OK, non copyable nor movable
308*605b8dadSCongcong Cai };
309*605b8dadSCongcong Cai 
310b70e6e96SCarlos Galvez // Test composition
311b70e6e96SCarlos Galvez struct ContainsNonCopyable
312b70e6e96SCarlos Galvez {
313b70e6e96SCarlos Galvez   NonCopyable x;
314b70e6e96SCarlos Galvez   int& y;
315b70e6e96SCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'y' of type 'int &' is a reference
316b70e6e96SCarlos Galvez };
317b70e6e96SCarlos Galvez 
318b70e6e96SCarlos Galvez struct ContainsNonMovable
319b70e6e96SCarlos Galvez {
320b70e6e96SCarlos Galvez   NonMovable x;
321b70e6e96SCarlos Galvez   int& y;
322b70e6e96SCarlos Galvez   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'y' of type 'int &' is a reference
323b70e6e96SCarlos Galvez };
324b70e6e96SCarlos Galvez 
325b70e6e96SCarlos Galvez struct ContainsNonCopyableNonMovable
326b70e6e96SCarlos Galvez {
327b70e6e96SCarlos Galvez   NonCopyableNonMovable x;
328b70e6e96SCarlos Galvez   int& y;  // OK, non copyable nor movable
329b70e6e96SCarlos Galvez };
330b70e6e96SCarlos Galvez 
331b70e6e96SCarlos Galvez struct ContainsBothNonCopyableAndNonMovable
332b70e6e96SCarlos Galvez {
333b70e6e96SCarlos Galvez   NonCopyable x;
334b70e6e96SCarlos Galvez   NonMovable y;
335b70e6e96SCarlos Galvez   int& z;  // OK, non copyable nor movable
336b70e6e96SCarlos Galvez };
337b70e6e96SCarlos Galvez 
338b70e6e96SCarlos Galvez // If copies are deleted and moves are not declared, moves are not implicitly declared,
339b70e6e96SCarlos Galvez // so the class is also not movable and we should not warn
340b70e6e96SCarlos Galvez struct NonCopyableMovesNotDeclared
341b70e6e96SCarlos Galvez {
342b70e6e96SCarlos Galvez   NonCopyableMovesNotDeclared(NonCopyableMovesNotDeclared const&) = delete;
343b70e6e96SCarlos Galvez   NonCopyableMovesNotDeclared& operator=(NonCopyableMovesNotDeclared const&) = delete;
344b70e6e96SCarlos Galvez 
345b70e6e96SCarlos Galvez   int& x;  // OK, non copyable nor movable
346b70e6e96SCarlos Galvez };
347b70e6e96SCarlos Galvez 
348b70e6e96SCarlos Galvez // If moves are deleted but copies are not declared, copies are implicitly deleted,
349b70e6e96SCarlos Galvez // so the class is also not copyable and we should not warn
350b70e6e96SCarlos Galvez struct NonMovableCopiesNotDeclared
351b70e6e96SCarlos Galvez {
352b70e6e96SCarlos Galvez   NonMovableCopiesNotDeclared(NonMovableCopiesNotDeclared&&) = delete;
353b70e6e96SCarlos Galvez   NonMovableCopiesNotDeclared& operator=(NonMovableCopiesNotDeclared&&) = delete;
354b70e6e96SCarlos Galvez 
355b70e6e96SCarlos Galvez   int& x;  // OK, non copyable nor movable
356b70e6e96SCarlos Galvez };
357