0

Running clang-tidy on the following (simplified) code:

struct Base {
    Base() = default;
    virtual ~Base() = default;
    Base(const Base&) = delete;
    Base& operator=(const Base&) = delete;
    Base(Base&&) = delete; // not really needed
    Base& operator=(Base&&) = delete; // not really needed
};

template<typename T>
struct Crtp : Base {};

struct Derived : Crtp<Derived> {
    ~Derived() noexcept override { /*...*/ }
};

Produces the following warning:
Class 'Derived' defines a non-default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions,hicpp-special-member-functions]

Why? Those member functions are deleted in the Base class.

I even tried the following in .clang-tidy:

CheckOptions: [
  { key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor, value: true },
  { key: hicpp-special-member-functions.AllowSoleDefaultDtor, value: true },
  { key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions, value: true },
  { key: hicpp-special-member-functions.AllowMissingMoveFunctions, value: true },
  { key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctionsWhenCopyIsDeleted, value: true },
  { key: hicpp-special-member-functions.AllowMissingMoveFunctionsWhenCopyIsDeleted, value: true }
]

But it didn't make any difference.

Is it a bug in clang-tidy, or am I missing something?

Alex O
  • 1,429
  • 2
  • 13
  • 20
  • 2
    Do you know what the Rule of 5 is? – sweenish Oct 29 '22 at 01:19
  • I think this is intentional. The point of the rule-of-5 is to avoid mistakes by making sure that the implicitly-defined member functions (if any) do not have the wrong semantics for the additional behavior defined in the destructor. If you have to look up the base class first to know whether or not that is satisfied, then it is not very effective at avoiding such mistakes. – user17732522 Oct 29 '22 at 05:54
  • 1
    More of, `Base::Base` != `Derived::Derived`. You deleted overloads of the former, not ones of the latter. Dunno what original code meant to do with non-copyable base class... sometimes it's better to keep it simple. – Swift - Friday Pie Oct 29 '22 at 18:20
  • If the base class is non-copyable, doesn't it ensure that the derived class will be as well? – Alex O Oct 30 '22 at 04:33

0 Answers0