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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2017-01-13
     Ever confirmed|0                           |1

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
And then if we dare to define a non-member function that's part  of the
deprecated class' API we end up with five warnings:

struct [[deprecated("D is bad mmmkay")]] D {
  void f(const D&);
};

void D::f(const D&) { }

D operator+(const D&, const D&);

d.cc:2:18: warning: ‘D’ is deprecated [-Wdeprecated-declarations]
   void f(const D&);
                  ^
d.cc:5:19: warning: ‘D’ is deprecated [-Wdeprecated-declarations]
 void D::f(const D&) { }
                   ^
d.cc:7:31: warning: ‘D’ is deprecated: D is bad mmmkay
[-Wdeprecated-declarations]
 D operator+(const D&, const D&);
                               ^
d.cc:1:42: note: declared here
 struct [[deprecated("D is bad mmmkay")]] D {
                                          ^
d.cc:7:31: warning: ‘D’ is deprecated [-Wdeprecated-declarations]
 D operator+(const D&, const D&);
                               ^
d.cc:7:31: warning: ‘D’ is deprecated [-Wdeprecated-declarations]

Again, one is probably enough. The operator uses D, but giving the same warning
three times is unhelpful.

Clang gives three warnings here too, but it's smart enough to not warn if the
function that refers to D is also deprecated. In that case presumably it's part
of the same API, and like the member function case it must be possible for
entities within a "module" to refer to each other even if they are deprecated.
Otherwise writing the module becomes a pain due to all the warnings.

Clang issues no warnings at all for this code:

struct [[deprecated("D is bad mmmkay")]] D {
  void f(const D&);
};

void D::f(const D&) { }

[[deprecated("D is bad ")]] D operator+(const D&, const D&);

GCC gives:

d.cc:2:18: warning: ‘D’ is deprecated [-Wdeprecated-declarations]
   void f(const D&);
                  ^
d.cc:5:19: warning: ‘D’ is deprecated [-Wdeprecated-declarations]
 void D::f(const D&) { }
                   ^
d.cc:7:59: warning: ‘D’ is deprecated: D is bad mmmkay
[-Wdeprecated-declarations]
 [[deprecated("D is bad ")]] D operator+(const D&, const D&);
                                                           ^
d.cc:1:42: note: declared here
 struct [[deprecated("D is bad mmmkay")]] D {
                                          ^
d.cc:7:59: warning: ‘D’ is deprecated [-Wdeprecated-declarations]
 [[deprecated("D is bad ")]] D operator+(const D&, const D&);
                                                           ^
d.cc:7:59: warning: ‘D’ is deprecated [-Wdeprecated-declarations]


Another possible heuristic would be to suppress deprecated warnings for
declarations in the same header. A function declared in the same header as D is
probably part of the same API. Warn about uses outside that header, but not
within it. But simply suppressing warnings for functions marked deprecated is
probably good enough.

Reply via email to