The __attribute__((deprecated)): * cannot be used with inline methods [or: the info needs to say how to do so] I get a parser error if I put it in the obvious place * is ignored when used with a pure virtual method (though I'm pleased to see it does get inherited - if I change hook's type to Derived* I *do* get my warning, even without the attribute overtly on Derived::Virtue) * gets a report referencing the *definition* rather than the *declaration* (as advertised) if the method is used after its definition. Environment: System: Linux whorl 2.4.18-1-686-smp #1 SMP Sun Feb 1 04:12:27 MST 2004 i686 GNU/Linux Architecture: i686 host: i486-pc-linux-gnu build: i486-pc-linux-gnu target: i486-pc-linux-gnu configured with: ../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --enable-__cxa_atexit --enable-clocale=gnu --enable-debug --enable-java-gc=boehm --enable-java-awt=xlib --enable-objc-gc i486-linux How-To-Repeat: * Save the following to a file named deprecate.cpp; make deprecated will then compile it (see comment at end recording output). Observe that the use of Virtue gets no warning. Observe that second warning for Method() references defn, not decl. * Uncomment the attribute on Inline, make deprecated, see parser error. It is possible to get round this; declare it with attribute in the class body, then have a separate inline int Base::Inline() { return 0; } after the class body. class Base { public: virtual int Virtue() __attribute__((deprecated)) = 0; int Inline() // __attribute__((deprecated)) // causes parser error { return 0; } int Method() __attribute__((deprecated)); // declaration }; class Derived : public Base { /* Adding __attribute__((deprecated)) to this makes no difference, but * that's sensible enough: */ int Virtue(); }; int Derived::Virtue() { return Method(); } // warning correctly references declaration int Base::Method() { return 42; } // definition int main(void) { Derived obj; Base *hook = &obj; return hook->Virtue() // no warning about Virtue ! + hook->Method(); // warning references definition, not declaration } /* make -k deprecate CXXFLAGS=-fmessage-length=0 g++ -fmessage-length=0 deprecate.cpp -o deprecate deprecate.cpp: In member function `virtual int Derived::Virtue()': deprecate.cpp:14: warning: `Method' is deprecated (declared at deprecate.cpp:6) deprecate.cpp: In function `int main()': deprecate.cpp:21: warning: `Method' is deprecated (declared at deprecate.cpp:15) */
Fix: Not known.
Confirmed. There are multiple problems: ---------- struct B { virtual int foo() __attribute__((deprecated)); }; int main(void) { ((B*)0)->foo(); } ---------- The compiler should warn, but doesn't. It does if the 'virtual' is removed. Problem number two is this: ------------ struct B { int foo() __attribute__((deprecated)) {}; }; ------------ This doesn't compile with gcc up to 3.3.4. However, it is already fixed with the new parser in 3.4.0, so this is ok now. W.
Subject: Re: __attribute__((deprecated)) broken with inline, ignored with pure virtual, misreported after definition Nice to see the inline problem is fixed already :^) Unless it's also been fixed in the interval, problem number three is this: ----------- struct B { void foo() __attribute__((deprecated)); // declaration // documentation of why it's deprecated, how to dispense with it } void B::foo() { return; } // definition void demo(void) { ((B*)0)->foo(); } // gets warning ----------- the compiler's warning says foo was declared at line 5 when it was actually declared at line 2. If (as will be true in any real example) the declaration is in a header file and the definition is in a separate source file, whoever comes along to fix the warning is going to be directed to the definition, which doesn't have the documentation of why the method is decremented and how to do without it. This will be particularly monstrous if in fact the attribute is on a distant base class of B (I can't test this because of problem number one): the implementation of (some class in the same compilation unit as) B calls the foo of a B object after B has defined foo; the warning *really* needs to reference the far off header file which defines the base class ... being told about B's implementation of foo will be little use ! Eddy.
Confirmed the last problem as well. In the example you pasted, you were missing a semicolon after the the struct declaration. Here is a corrected version: ------------ struct B { void foo() __attribute__((deprecated)); }; void B::foo() {} void demo() { ((B*)0)->foo(); } ------------- This yields: g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ -c x.cc x.cc: In function `void demo()': x.cc:6: warning: `foo' is deprecated (declared at x.cc:5) with indeed the warning referencing the _definition_, not the _declaration_. To summarize: the failures we still have are the one in this comment as well as the first example in my comment #2. W.
For the last example I can confirm it also on the mainline, I think the problem is when creating the second decl for the definition. For the virtual issue is that there is an indirect call to the function's entry in the vtable and that entry does not have the attribute on it.
About #3: When we see the definition of a function, we don't keep information about where it was first declared. For member functions, we could give the source position of the class if that would be helplful.
Subject: Bug 15269 Author: jason Date: Sun Sep 23 04:37:26 2007 New Revision: 128682 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128682 Log: PR c++/15269 * call.c (build_over_call): Warn about deprecated virtuals. Added: trunk/gcc/testsuite/g++.dg/warn/deprecated-4.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c
Virtual problem fixed for 4.3.0.
Subject: Re: __attribute__((deprecated)) broken with inline, ignored with pure virtual, misreported after definition > Virtual problem fixed for 4.3.0. Yay ! Thank you :-) Eddy.
So to summary here, the only problem left is the following testcase: // { dg-do compile } struct B { void foo() __attribute__((deprecated)); // { dg-message "note" } }; void B::foo() {} // { dg-bogus "" } void demo() { ((B*)0)->foo(); } // { dg-warning "" }