Subject: bin/4670: Remove spurious g++ warnings
To: None <gnats-bugs@gnats.netbsd.org>
From: None <bgrayson@ece.utexas.edu>
List: netbsd-bugs
Date: 12/11/1997 12:04:25
>Number:         4670
>Category:       bin
>Synopsis:       Remove spurious g++ warnings when redefining new and delete
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Dec 11 10:05:00 1997
>Last-Modified:
>Originator:     Brian Grayson
>Organization:
	Parallel and Distributed Systems
	Electrical and Computer Engineering
	The University of Texas at Austin
>Release:        early Dec. 1997
>Environment:
NetBSD marvin 1.3_BETA NetBSD 1.3_BETA (MARVIN) #21: Tue Dec  2 17:07:42 CST 1997     bgrayson@marvin:/a/c3p0/home/c3p0/src/sys/arch/i386/compile/MARVIN i386

>Description:
	According to Stroustrup (section 13.10 of ``The C++
	Programming Language, Second Edition'') it is perfectly
	acceptable for a user to redefine the new and delete
	operators.  In addition, there is no reason why these
	new definitions can't be inlineable.  However, gcc
	provides spurious warnings when such redefinitions are
	done.  The problem is that the warning code appears to
	not properly check whether or not the previous non-inline
	internal declaration was ever used.  As an example, the
	1-liner .cc file:

	void operator delete (void* p) { }

	will compile with no problems.  Add ``inline'' before
	void, though, and gcc improperly warns about a
	redeclaration after a use.  Well, it's pretty obvious
	that delete hasn't been used yet if this is the first
	line in the file.

	inline void operator delete (void* p) { }

% /usr/bin/gcc /tmp/foo.cc
/tmp/foo.cc: In function `void operator delete(void *)':
/tmp/foo.cc:1: warning: `void operator delete(void *)' was used
		  before it was declared inline
<internal>:1: warning: previous non-inline declaration here

>How-To-Repeat:
	
>Fix:
	The following patch will eliminate these spurious
	warnings.  Unfortunately, it may also eliminate warnings
	where the noninline declaration _was_ really used before
	the redeclaration.  A gcc guru may be able to figure out
	the appropriate predicate to use  -- perhaps a check
	of TREE_USED(olddecl)?  Or it may be that the internal
	decls for new/delete/new[]/delete[] already mark the
	addressable_flag, when it shouldn't really be marked,
	which is a deeper bug.

	
src/gnu/usr.bin/gcc/common
--- decl.c.orig Wed Dec 10 12:33:52 1997
+++ decl.c      Thu Dec 11 11:18:53 1997
@@ -2685,7 +2685,15 @@
                }
              else
 #endif
-             if (TREE_ADDRESSABLE (olddecl))
+             /*  If the previous declaration was an "<internal>"
+                 one, don't bother with the warning.  Notice that
+                 this will not print a warning if an <internal>
+                 noninline function is actually _used_ before the
+                 redeclaration, so this isn't the best fix.  The
+                 primary reason for this fix is to allow the
+                 user to redefine `new' and `delete' as inline.  */
+             if (TREE_ADDRESSABLE (olddecl)
+                 && strcmp(DECL_SOURCE_FILE(olddecl),"<internal>"))
                {
                  cp_pedwarn ("`%#D' was used before it was declared inline",
                              newdecl);

>Audit-Trail:
>Unformatted: