1 // RUN: %check_clang_tidy %s performance-trivially-destructible %t 2 // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp 3 // RUN: clang-tidy %t.cpp -checks='-*,performance-trivially-destructible' -fix 4 // RUN: clang-tidy %t.cpp -checks='-*,performance-trivially-destructible' -warnings-as-errors='-*,performance-trivially-destructible' 5 6 struct TriviallyDestructible1 { 7 int a; 8 }; 9 10 struct TriviallyDestructible2 : TriviallyDestructible1 { 11 ~TriviallyDestructible2() = default; 12 TriviallyDestructible1 b; 13 }; 14 15 struct NotTriviallyDestructible1 : TriviallyDestructible2 { 16 ~NotTriviallyDestructible1(); 17 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: class 'NotTriviallyDestructible1' can be made trivially destructible by defaulting the destructor on its first declaration [performance-trivially-destructible] 18 // CHECK-FIXES: ~NotTriviallyDestructible1() = default; 19 TriviallyDestructible2 b; 20 }; 21 22 NotTriviallyDestructible1::~NotTriviallyDestructible1() = default; // to-be-removed 23 // CHECK-MESSAGES: :[[@LINE-1]]:28: note: destructor definition is here 24 // CHECK-FIXES: {{^}}// to-be-removed 25 26 // Don't emit for class template with type-dependent fields. 27 template <class T> 28 struct MaybeTriviallyDestructible1 { 29 ~MaybeTriviallyDestructible1() noexcept; 30 T t; 31 }; 32 33 template <class T> 34 MaybeTriviallyDestructible1<T>::~MaybeTriviallyDestructible1() noexcept = default; 35 36 // Don't emit for specializations. 37 template struct MaybeTriviallyDestructible1<int>; 38 39 // Don't emit for class template with type-dependent bases. 40 template <class T> 41 struct MaybeTriviallyDestructible2 : T { 42 ~MaybeTriviallyDestructible2() noexcept; 43 }; 44 45 template <class T> 46 MaybeTriviallyDestructible2<T>::~MaybeTriviallyDestructible2() noexcept = default; 47 48 // Emit for templates without dependent bases and fields. 49 template <class T> 50 struct MaybeTriviallyDestructible1<T *> { 51 ~MaybeTriviallyDestructible1() noexcept; 52 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: class 'MaybeTriviallyDestructible1<T *>' can be made trivially destructible by defaulting the destructor on its first declaration [performance-trivially-destructible] 53 // CHECK-FIXES: ~MaybeTriviallyDestructible1() noexcept = default; 54 TriviallyDestructible1 t; 55 }; 56 57 template <class T> 58 MaybeTriviallyDestructible1<T *>::~MaybeTriviallyDestructible1() noexcept = default; // to-be-removed 59 // CHECK-MESSAGES: :[[@LINE-1]]:35: note: destructor definition is here 60 // CHECK-FIXES: {{^}}// to-be-removed 61 62 // Emit for explicit specializations. 63 template <> 64 struct MaybeTriviallyDestructible1<double>: TriviallyDestructible1 { 65 ~MaybeTriviallyDestructible1() noexcept; 66 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: class 'MaybeTriviallyDestructible1<double>' can be made trivially destructible by defaulting the destructor on its first declaration [performance-trivially-destructible] 67 // CHECK-FIXES: ~MaybeTriviallyDestructible1() noexcept = default; 68 }; 69 70 MaybeTriviallyDestructible1<double>::~MaybeTriviallyDestructible1() noexcept = default; // to-be-removed 71 // CHECK-MESSAGES: :[[@LINE-1]]:38: note: destructor definition is here 72 // CHECK-FIXES: {{^}}// to-be-removed 73 74 struct NotTriviallyDestructible2 { 75 virtual ~NotTriviallyDestructible2(); 76 }; 77 78 NotTriviallyDestructible2::~NotTriviallyDestructible2() = default; 79 80 struct NotTriviallyDestructible3: NotTriviallyDestructible2 { 81 ~NotTriviallyDestructible3(); 82 }; 83 84 NotTriviallyDestructible3::~NotTriviallyDestructible3() = default; 85