Bug 142423 - Incorrect scope for for inline class friend functions
Summary: Incorrect scope for for inline class friend functions
Status: CLOSED UPSTREAM
Alias: None
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: gcc3 (Show other bugs)
(Show other bugs)
Version: 3.0
Hardware: All Linux
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact:
URL:
Whiteboard:
Keywords:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2004-12-09 17:44 UTC by Fedor Pikus
Modified: 2007-11-30 22:07 UTC (History)
2 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2004-12-29 12:56:20 UTC
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

Description Fedor Pikus 2004-12-09 17:44:04 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.3)
Gecko/20041101

Description of problem:
The following program should not compile:
class A
{
    public:
    A( int x0 = 0 ) : x( x0 ) {}
    friend int foo( const A& a ) { return a.x; }
    int x;
};  
    
int main() 
{   
    A a;
    int i = foo( 0 );
}

the call to foo() should require argument-dependent lookup but since
the argument is "int" not "A&", ADL cannot be performed. 

This can lead to rather bizarre behaviour, for example:
#include <iostream>
using namespace std;

template <typename T> class A
{
    public:
    A( T x0 = 0 ) : x( x0 ) {}
    friend T foo( const A& a ) { cout << "A::foo" << endl; return a.x; }
    T x;
};

template <typename T> class B
{
    public:
    B( T x0 = 0 ) : x( x0 ) {}
    friend T foo( const B& a ) { cout << "B::foo" << endl; return a.x; }
    T x;
};

int main()
{
    {
        A<int> a = 0;
        int i = foo( a ); 
        int j = foo( 0 ); 
    }
    {
        B<int> b = 0;
        int i = foo( b ); 
        int j = foo( 0 ); 
    }
}

In this program the error message is:
lookup4.C: In function `int main()':
lookup4.C:30: call of overloaded `foo(int)' is ambiguous
lookup4.C:8: candidates are: int foo(const A<int>&)
lookup4.C:16:                 int foo(const B<int>&)

Call on line 30 is ambiguous but call on line 25 is not (and indeed
compiles if line 30 is commented out, A::foo is called). 

Version-Release number of selected component (if applicable):
gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-34)

Comment 2 Jason Merrill 2004-12-27 19:43:22 UTC
g++ still injects the names of friend functions into the enclosing namespace;
this is obsolete behaviour which was removed from the language in favor of
argument-dependent lookup of friend functions, but g++ has not yet caught up.

Comment 3 Jakub Jelinek 2004-12-29 12:56:20 UTC
Given that even current CVS HEAD doesn't handle this, I'm closing this as
UPSTREAM.  When/if upstream fixes this and if the fix is simple enough, we might
consider backporting it (but RHEL4 has certainly bigger chance of backporting
that than RHEL3).

Jason, is there any PR about this in gcc.gnu.org/bugzilla?


Note You need to log in before you can comment on or make changes to this bug.