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
128
129
130
131
132
133
134
135
136
137
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <sal/config.h>

#include <salhelper/simplereferenceobject.hxx>

#include "unnecessaryoverride-dtor.hxx"

struct NonVirtualBase {};

struct NonVirtualDerived1: NonVirtualBase {
    ~NonVirtualDerived1() {} // expected-error {{unnecessary user-declared destructor [loplugin:unnecessaryoverride]}}
};

struct NonVirtualDerived2: NonVirtualBase {
    virtual ~NonVirtualDerived2() {}
};

struct PrivateDerived: VirtualBase {
private:
    ~PrivateDerived() override {}
};

struct ProtectedDerived: VirtualBase {
protected:
    ~ProtectedDerived() override {}
};

IncludedDerived2::~IncludedDerived2() {}

struct Incomplete: salhelper::SimpleReferenceObject {};

IncludedDerived3::IncludedDerived3() {}

IncludedDerived3::~IncludedDerived3() {}

// vmiklos likes these because he can quickly add a DEBUG or something similar without
// massive recompile
IncludedNotDerived::~IncludedNotDerived() {}

struct NoExSpecDerived: VirtualBase {
    ~NoExSpecDerived() override {} // expected-error {{unnecessary user-declared destructor [loplugin:unnecessaryoverride]}}
};

struct NoThrowDerived: VirtualBase {
    ~NoThrowDerived() throw () override {} // expected-error {{unnecessary user-declared destructor [loplugin:unnecessaryoverride]}}
};

struct NoexceptDerived: VirtualBase {
    ~NoexceptDerived() noexcept override {} // expected-error {{unnecessary user-declared destructor [loplugin:unnecessaryoverride]}}
};

struct NoexceptTrueDerived: VirtualBase {
    ~NoexceptTrueDerived() noexcept(true) override {} // expected-error {{unnecessary user-declared destructor [loplugin:unnecessaryoverride]}}
};

#if 0
struct NoexceptFalseBase {
    virtual ~NoexceptFalseBase() noexcept(false) {}
};

struct NoexceptFalseDerived: NoexceptFalseBase {
    ~NoexceptFalseDerived() noexcept(false) override {}
};
#endif

struct NoDtorDerived: VirtualBase {};

struct DefaultDerived1: VirtualBase {
    ~DefaultDerived1() override = default; // expected-error {{unnecessary user-declared destructor [loplugin:unnecessaryoverride]}}
};

struct DefaultDerived2: VirtualBase {
    ~DefaultDerived2() override; // expected-note {{declared here [loplugin:unnecessaryoverride]}}
};

DefaultDerived2::~DefaultDerived2() = default; // expected-error {{unnecessary user-declared destructor [loplugin:unnecessaryoverride]}}

struct EmptyDerived1: VirtualBase {
    ~EmptyDerived1() override {}; // expected-error {{unnecessary user-declared destructor [loplugin:unnecessaryoverride]}}
};

struct EmptyDerived2: VirtualBase {
    ~EmptyDerived2() override; // expected-note {{declared here [loplugin:unnecessaryoverride]}}
};

EmptyDerived2::~EmptyDerived2() {} // expected-error {{unnecessary user-declared destructor [loplugin:unnecessaryoverride]}}

struct NonEmptyDerived: VirtualBase {
    ~NonEmptyDerived() override { (void) 0; }
};

struct CatchDerived: VirtualBase {
    ~CatchDerived() override try {} catch (...) {}
};

struct DeleteBase {
    virtual ~DeleteBase() = delete;
};

struct DeleteDerived: DeleteBase {
    ~DeleteDerived() override = delete;
};

struct PureBase {
    virtual ~PureBase() = 0;
};

struct PureDerived: PureBase {
    ~PureDerived() override {} // expected-error {{unnecessary user-declared destructor [loplugin:unnecessaryoverride]}}
};

struct CompleteBase {
    ~CompleteBase() {} // expected-error {{unnecessary user-declared destructor [loplugin:unnecessaryoverride]}}
};

// <sberg> noelgrandin, there's one other corner case one can imagine:
// a class defined in a .hxx with the dtor declared (but not defined) as inline in the .hxx,
// and then defined in the cxx (making it effectively only callable from within the cxx);
// removing the dtor declaration from the class definition would change the dtor to be callable from everywhere
MarkedInlineButNotDefined::~MarkedInlineButNotDefined() {}

// avoid loplugin:unreffun:
int main() {
    (void) NonVirtualDerived1();<--- Instance of 'NonVirtualDerived1' object is destroyed immediately.
    (void) DefaultDerived1();<--- Instance of 'DefaultDerived1' object is destroyed immediately.
    (void) CompleteBase();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */