Bug 38850 - [4.4 Regression] Cannot find inline friend function in template class when called from within a template function
Summary: [4.4 Regression] Cannot find inline friend function in template class when ca...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.4.0
: P2 normal
Target Milestone: 4.2.5
Assignee: Jason Merrill
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2009-01-14 20:51 UTC by Neil Vachharajani
Modified: 2009-01-16 06:08 UTC (History)
1 user (show)

See Also:
Host: i686-unknown-linux-gnu
Target: i686-unknown-linux-gnu
Build: i686-unknown-linux-gnu
Known to work: 4.1.2
Known to fail: 4.4.0
Last reconfirmed: 2009-01-15 23:13:59


Attachments
Test case program (239 bytes, text/x-c++src)
2009-01-14 20:53 UTC, Neil Vachharajani
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Neil Vachharajani 2009-01-14 20:51:57 UTC
Compiling the following program:

template <typename VType>
class Vector2 {
 private:
  VType c_[2];
 public:
  typedef Vector2<VType> Self;

  Vector2(const VType x, const VType y) {
    c_[0] = x;
    c_[1] = y;
  }

  friend inline Self Max(const Self &v1, const Self &v2) {
    return Self(v1.c_[0], v1.c_[1]);
  }
};

template <class T>
Vector2<float> foo(T x) {
  Vector2<float> y(0,0);
  return Max(y, y);
}

int main() {
  foo(3);
  return 0;
}

gives the following error:

test.cc: In function 'Vector2<float> foo(T) [with T = int]':
test.cc:25:   instantiated from here
test.cc:13: error: no matching function for call to 'Max(Vector2<float>&, Vector2<float>&)'

When compiled using GCC 4.4.0 trunk.  The command line used for the compile is:
g++ -c test.cc

The output of gcc -v is:
Using built-in specs.
Target: i686-unknown-linux-gnu
Configured with: src/configure --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-c99 --enable-long-long --with-gnu-as --with-gnu-ld --build=i686-host_pc-linux-gnu --host=i686-host_pc-linux-gnu --enable-shared=libgcc,libmudflap,libssp,libstdc++ --enable-languages=c,c++,fortran --with-gmp=/usr/grte/v1 --prefix=/tmp/gcc-4.3.1-glibc-2.3.6-grte/i686-unknown-linux-gnu --target=i686-unknown-linux-gnu --enable-static-nss --with-arch=pentium3 --with-tune=pentium4
Thread model: posix
gcc version 4.4.0 20090114 (experimental) 
COLLECT_GCC_OPTIONS='-v' '-c' '-shared-libgcc' '-mtune=pentium4' '-march=pentium3'
Comment 1 Neil Vachharajani 2009-01-14 20:53:29 UTC
Created attachment 17103 [details]
Test case program
Comment 2 Andrew Pinski 2009-01-14 21:24:03 UTC
I think this code is invalid as the call to Max is not going to be dependent as the arguments are not dependent and can be looked up at the time the function is defined.
Comment 3 Neil Vachharajani 2009-01-14 21:30:16 UTC
(In reply to comment #2)
> I think this code is invalid as the call to Max is not going to be dependent as
> the arguments are not dependent and can be looked up at the time the function
> is defined.
> 

I don't think I follow.  While the arguments to Max are not dependent, other code inside of foo could be dependent on T (in the example, no such code exists).  Shouldn't the fact that the function can be looked up at definition time make this code legal?
Comment 4 Richard Biener 2009-01-14 21:46:06 UTC
From a first look Max should be found during argument-dependent name-lookup.  EDG
confirms this theory.  gcc 4.1 accepts this code.
Comment 5 Andrew Pinski 2009-01-14 21:51:05 UTC
Oh yes it only fails inside a template context.
Comment 6 Andrew Pinski 2009-01-14 21:53:39 UTC
Related to PR 34870 and 37804.

friend and templates never got along.
Comment 7 Jason Merrill 2009-01-16 04:55:57 UTC
4.2 and 4.3 handle this fine, I don't know why it was marked as a 4.2/4.3 regression.
Comment 8 Jason Merrill 2009-01-16 05:04:40 UTC
Subject: Bug 38850

Author: jason
Date: Fri Jan 16 05:04:26 2009
New Revision: 143422

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143422
Log:
        PR c++/38850
        * pt.c (tsubst_copy_and_build): Tell finish_call_expr to
        accept hidden friends.

Added:
    trunk/gcc/testsuite/g++.dg/template/koenig6.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c
    trunk/gcc/testsuite/ChangeLog

Comment 9 Jason Merrill 2009-01-16 06:08:24 UTC
Subject: Bug 38850

Author: jason
Date: Fri Jan 16 06:08:09 2009
New Revision: 143423

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143423
Log:
        PR c++/38850
        * pt.c (tsubst_copy_and_build): Tell finish_call_expr to
        accept hidden friends.

Added:
    branches/gcc-4_2-branch/gcc/testsuite/g++.dg/template/koenig6.C
      - copied unchanged from r143422, trunk/gcc/testsuite/g++.dg/template/koenig6.C
Modified:
    branches/gcc-4_2-branch/gcc/cp/ChangeLog
    branches/gcc-4_2-branch/gcc/cp/pt.c
    branches/gcc-4_2-branch/gcc/testsuite/ChangeLog

Comment 10 Jason Merrill 2009-01-16 06:08:32 UTC
Subject: Bug 38850

Author: jason
Date: Fri Jan 16 06:08:20 2009
New Revision: 143424

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143424
Log:
        PR c++/38850
        * pt.c (tsubst_copy_and_build): Tell finish_call_expr to
        accept hidden friends.

Added:
    branches/gcc-4_3-branch/gcc/testsuite/g++.dg/template/koenig6.C
      - copied unchanged from r143422, trunk/gcc/testsuite/g++.dg/template/koenig6.C
Modified:
    branches/gcc-4_3-branch/gcc/cp/ChangeLog
    branches/gcc-4_3-branch/gcc/cp/pt.c
    branches/gcc-4_3-branch/gcc/testsuite/ChangeLog

Comment 11 Jason Merrill 2009-01-16 06:08:50 UTC
Fixed.