Bug 15269 - __attribute__((deprecated)) broken with inline, ignored with pure virtual, misreported after definition
Summary: __attribute__((deprecated)) broken with inline, ignored with pure virtual, mi...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.3
: P3 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2004-05-03 18:08 UTC by eddy@opera.com
Modified: 2021-08-12 22:27 UTC (History)
4 users (show)

See Also:
Host: i486-pc-linux-gnu
Target: i486-pc-linux-gnu
Build: i486-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2021-08-11 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description eddy@opera.com 2004-05-03 18:08:49 UTC
	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)
*/
Comment 1 eddy@opera.com 2004-05-03 18:08:49 UTC
Fix:
	Not known.
Comment 2 Wolfgang Bangerth 2004-05-03 18:39:50 UTC
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. 
Comment 3 eddy@opera.com 2004-05-03 19:08:10 UTC
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.
Comment 4 Wolfgang Bangerth 2004-05-03 19:17:20 UTC
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. 
Comment 5 Andrew Pinski 2004-05-03 19:20:12 UTC
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. 
Comment 6 Jason Merrill 2007-09-23 04:33:18 UTC
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.
Comment 7 Jason Merrill 2007-09-23 04:37:43 UTC
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

Comment 8 Jason Merrill 2007-09-23 04:39:44 UTC
Virtual problem fixed for 4.3.0.
Comment 9 eddy@opera.com 2007-09-25 15:54:05 UTC
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.
Comment 10 Andrew Pinski 2021-08-11 20:25:53 UTC
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 "" }