https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102168

            Bug ID: 102168
           Summary: -Wnon-virtual-dtor shouldn't fire for protected dtor
                    in a class with a friend declaration
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: i at maskray dot me
  Target Milestone: ---

class base;

class b {
public:
  void del(base *x);
};

class base {
  friend b;
public:
  virtual void anchor();
protected:
  virtual  // why is this needed?
  ~base() = default;
};

class derived final : public base { 
public: 
  ~derived() {}
};

void b::del(base *x) {
  delete x;
}

% g++ -c -Wnon-virtual-dtor a.cc
a.cc:8:7: warning: ‘class base’ has virtual functions and accessible
non-virtual destructor [-Wnon-virtual-dtor]
    8 | class base {
      |       ^~~~
a.cc:17:7: warning: base class ‘class base’ has accessible non-virtual
destructor [-Wnon-virtual-dtor]
   17 | class derived final : public base {
      |       ^~~~~~~


This diagnostic is due to a friend declaration because technically the friend
can invoke the dtor.

However, this seems a bit dumb (https://reviews.llvm.org/rG4852c770fe87)
It just checks the existence of friend, not actually checking whether the dtor
is actually used.
Checking whether the dtor is actually needed requires dataflow analysis (like
frontend devirtualization), which is apparently too heavy and may not fit into
a compiler diagnostic.
In addition, if the friend class ever uses the dtor, it'd trigger
-Wdelete-non-virtual-dtor.

Now to suppress the diagnostic, we have to add a `virtual`, wasting 2 entries
in the vtable and emitting unneeded D0/D2.

Reply via email to