First Last Prev Next    No search results available      Search page      Enter new bug
Bug#: 15629
Product:  
Component:  
Status: RESOLVED
Resolution: FIXED
Assigned To: Mark Mitchell <mark@codesourcery.com>
Host:
Reported against  
Priority:  
Severity:  
Target Milestone:  
 
 
Target:
Reporter: Yueh-Wei Hu (­J©¨°¶) <ywhu@nmi.iii.org.tw>
Add CC:
CC:
Remove selected CCs
Build:
URL:
Summary:
Keywords:
Known to work:
Known to fail:

Attachment Description Type Created Size Actions
Create a New Attachment (proposed patch, testcase, etc.) View All

Bug 15629 depends on: Show dependency tree
Show dependency graph
Bug 15629 blocks:

Additional Comments:






View Bug Activity   |   Format For Printing   |   Clone This Bug


Description:   Last confirmed: 2004-05-26 11:59 Opened: 2004-05-24 08:18
Hi,

When I use friend function templates in a class template, the function
overloading doesn't happend.

The following is the source.

==============================================================

#include <iostream>

template<int a, int b>
class T;

template<int a, int b>
void func(T<a, b> const * const t)
{
  std::cerr << "T<a, b>" << std::endl;
}

template<int a, int b>
class T
{
private:
  
  friend void func<a, b>(T<a, b> const * const t);
  friend void func<a>(T<a, 3> const * const t);
  
public:
  
  void ttt() const;
};

template<int a>
void
func(T<a, 3> const * const t)
{
  std::cerr << "T<a, 3>" << std::endl;
}


template<int a, int b>
void
T<a, b>::ttt() const
{
  func(this);
}

int
main()
{
  T<2, 3> t;
  
  t.ttt();
  
  return 0;
}

==============================================================

The error messages from gcc-3.2 is as following:

==============================================================

eee.cpp: In member function `void T<a, b>::ttt() const [with int a =
2, int b =
   3]':
eee.cpp:52:   instantiated from here
eee.cpp:44: call of overloaded `func(const T<2, 3>* const)' is
ambiguous
eee.cpp:8: candidates are: void func(const T<a, b>*) [with int a = 2,
int b =
   3]
eee.cpp:29:                 void func(const T<a, 3>*) [with int a = 2]
eee.cpp:8:                 void func(const T<a, b>*) [with int a = 2,
int b =
   3]
eee.cpp:29:                 void func(const T<a, 3>*) [with int a = 2]

==============================================================

However, when I use gcc-3.2, gcc-3.3, gcc-3.4 to compile my code, the
result is strange.

Here is my result:

1) gcc-3.2: can _not_ compile, the error message is copied and pasted
above.

2) gcc-3.3: can compile, but the result is

T<a, b>

[but I think it should be T<a, 3>]

3) gcc-3.4: can compile, but the result is

T<a, b>

[but I think it should be T<a, 3>]

< NOTE >

When I use 'struct' rather than 'class', and remove the 'friend'
declarations,
the function overloading works fine !

=============================================================
Question 2:
=============================================================

I added one more friend function declaration, and now, even gcc-3.3
doesn't compile my code.

The source code is as following:

==============================================================

#include <iostream>

template<int a, int b>
class T;

template<int a, int b>
void func(T<a, b> const * const t)
{
  std::cerr << "T<a, b>" << std::endl;
}

template<int a, int b>
class T
{
private:
  
  friend void func<a, b>(T<a, b> const * const t);
  friend void func<a>(T<a, 3> const * const t);
  friend void func<b>(T<3, b> const * const t); <-- add this -->
  
public:
  
  void ttt() const;
};

template<int a>
void
func(T<a, 3> const * const t)
{
  std::cerr << "T<a, 3>" << std::endl;
}

template<int b>  <-- add this definition -->
void
func(T<3, b> const * const t)
{
  std::cerr << "T<3, b>" << std::endl;
}

template<int a, int b>
void
T<a, b>::ttt() const
{
  func(this);
}

int
main()
{
  T<2, 3> t;
  
  t.ttt();
  
  return 0;
}

==============================================================

I can _not_ compile the code using gcc-3.2, and the error message for
gcc-3.2 is
like the one I posted above:

==============================================================

eee.cpp: In instantiation of `T<2, 3>':
eee.cpp:50:   instantiated from here
eee.cpp:19: ambiguous template specialization `func<3>' for `void
func(const
   T<3, 3>*)'
eee.cpp: In member function `void T<a, b>::ttt() const [with int a =
2, int b =
   3]':
eee.cpp:52:   instantiated from here
eee.cpp:44: call of overloaded `func(const T<2, 3>* const)' is
ambiguous
eee.cpp:8: candidates are: void func(const T<a, b>*) [with int a = 2,
int b =
   3]
eee.cpp:29:                 void func(const T<a, 3>*) [with int a = 2]
eee.cpp:8:                 void func(const T<a, b>*) [with int a = 2,
int b =
   3]
eee.cpp:29:                 void func(const T<a, 3>*) [with int a = 2]

==============================================================

Again, the following is the result when I compile it using gcc-3.2,
gcc-3.3 and gcc-3.4:

1) gcc-3.2: can _not_ compile, the error message posted above.
2) gcc-3.3: can _not_ compile, the error message just like the one
posted for gcc-3.2.
3) gcc-3.4: can compile, but the result is

T<a, b>

[but I think it should be T<a, 3>]

==============================================================

My environment:

1) Debian unstable
2) gcc-3.4.0 (Debian 20040516)
3) gcc-3.3.3 (Debian 20040422)
4) gcc-3.2.3
5) Command line options: none
6)

------- Comment #1 From Wolfgang Bangerth 2004-05-24 15:19 -------
OK, something is really screwed up here. Take this: 
----------------- 
#include <iostream> 
#define PRINT std::cerr << __PRETTY_FUNCTION__ << std::endl 
 
template<int a, int b> class T; 
 
template<int a, int b> void func(T<a, b> * t) { PRINT; } 
template<int a>        void func(T<a, 3> * t) { PRINT; } 
 
template<int a, int b> struct T { 
    friend void func<a, b>(T<a, b> * t); 
    friend void func<a>   (T<a, 3> * t); 
   
    void foo(); 
}; 
 
template<int a, int b> void T<a, b>::foo() { 
  func((T<2,3>*)0); 
} 
 
int main() { 
  func((T<2,3>*)0); 
  T<2,3>().foo(); 
} 
----------------------- 
 
Note that the call to func in main() is the same as the one in foo(), so 
it should really yield the same result. Alas, with gcc3.4, we get: 
 
g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc ; ./a.out 
void func(T<a, 3>*) [with int a = 2] 
void func(T<a, b>*) [with int a = 2, int b = 3] 
 
On the other hand, if we revert the order of the two calls in main(), we get 
a different result, namely a call to the general T<a,b> template as in the 
second line above. My inclination is to say that this is due to the fact that 
we only instantiate T<2,3> in the second call in main(), since the cast 
to (T<2,3>*)0 does not require instantiation of the template. Now, how that 
can affect the result I don't know -- presumably it has something to do with 
injecting the friend functions into the global namespace. This explains 
why reverting the calls in main() changes the result. 
 
What evades me, however, is why injecting the names should make any 
difference? Note that if I remove the friend declarations altogether, 
then we get two calls to the <a,3> template, irrespective of the call 
order in main(). I tend to think that this is what we should get in all 
cases, but would like to have a second opinion... 
 
W. 

------- Comment #2 From Giovanni Bajo 2004-05-26 11:59 -------
Confirmed as a regression. The reduced code in comment #1 by Wolfgang emits the 
following with GCC 2.95 (and EDG):

void func<2>(T<2,3> *)
void func<2>(T<2,3> *)

which is the correct behaviour. 3.0 - 3.2 even rejects this code, while from 
3.3 we have the wrong-code problem (the wrong specialization is chosen).

------- Comment #3 From Mark Mitchell 2004-05-31 18:48 -------
Working on a fix.

------- Comment #4 From CVS Commits 2004-05-31 21:04 -------
Subject: Bug 15629

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-3_4-branch
Changes by:	mmitchel@gcc.gnu.org	2004-05-31 21:04:15

Modified files:
	gcc/testsuite  : ChangeLog 
	gcc/cp         : ChangeLog call.c cp-tree.h cvt.c name-lookup.c 
	                 pt.c tree.c typeck.c 
	gcc/testsuite/g++.dg/ext: packed3.C packed4.C 
	gcc/testsuite/g++.dg/template: friend.C 
Added files:
	gcc/testsuite/g++.dg/expr: ptrmem5.C 
	gcc/testsuite/g++.dg/ext: packed6.C 
	gcc/testsuite/g++.dg/template: friend27.C friend28.C 
	gcc/testsuite/g++.dg/warn: Wreturn-1.C 

Log message:
	PR c++/15742
	* call.c (build_over_call): Set
	current_function_returns_abnormally even in template functions.
	
	PR c++/15696
	* cp-tree.h (invalid_nonstatic_memfn_p): New function.
	* cvt.c (convert_to_void): Use it.
	* typeck.c (invalid_nonstatic_memfn_p): New function.
	(decay_conversion): Use it.
	
	PR c++/15625
	* pt.c (tsubst_decl): Set DECL_FRIEND_CONTEXT for instantiated
	templates.
	
	PR c++/15629
	* name-lookup.c (arg_assoc_class): Do not find template
	specializations.
	
	PR c++/15209
	* tree.c (lvalue_p_1): Only consider the right-hand side of "."
	expressions when determining whether or not an express is packed.
	
	PR c++/15742
	* g++.dg/warn/Wreturn-1.C: New test.
	
	PR c++/15696
	* g++.dg/expr/ptrmem5.C: New test.
	
	PR c++/15625
	* g++.dg/template/friend27.C: New test.
	
	PR c++/15629
	* g++.dg/template/friend28.C: New test.
	* g++.dg/template/friend.C: Do not depend on <iostream>.  Add
	error message.
	
	PR c++/15209
	* g++.dg/ext/packed3.C: Remove bogus error.
	* g++.dg/ext/packed4.C: Remove bogus check.
	* g++.dg/ext/packed6.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3389.2.187&r2=1.3389.2.188
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3892.2.109&r2=1.3892.2.110
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/call.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.452.2.16&r2=1.452.2.17
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cp-tree.h.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.946.4.12&r2=1.946.4.13
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cvt.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.151.4.1&r2=1.151.4.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/name-lookup.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.34.2.13&r2=1.34.2.14
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.816.2.26&r2=1.816.2.27
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/tree.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.360.4.5&r2=1.360.4.6
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/typeck.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.519.2.18&r2=1.519.2.19
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/expr/ptrmem5.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed6.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed3.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.1&r2=1.1.24.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed4.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.1&r2=1.1.24.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend27.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend28.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.5&r2=1.5.56.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/warn/Wreturn-1.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1


------- Comment #5 From CVS Commits 2004-05-31 21:24 -------
Subject: Bug 15629

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	mmitchel@gcc.gnu.org	2004-05-31 21:24:31

Modified files:
	gcc/cp         : call.c cp-tree.h cvt.c name-lookup.c pt.c 
	                 tree.c typeck.c 
	gcc/testsuite/g++.dg/ext: packed3.C packed4.C 
	gcc/testsuite/g++.dg/template: friend.C 
Added files:
	gcc/testsuite/g++.dg/expr: ptrmem5.C 
	gcc/testsuite/g++.dg/ext: packed6.C 
	gcc/testsuite/g++.dg/template: friend27.C friend28.C 
	gcc/testsuite/g++.dg/warn: Wreturn-1.C 

Log message:
	PR c++/15742
	* call.c (build_over_call): Set
	current_function_returns_abnormally even in template functions.
	
	PR c++/15696
	* cp-tree.h (invalid_nonstatic_memfn_p): New function.
	* cvt.c (convert_to_void): Use it.
	* typeck.c (invalid_nonstatic_memfn_p): New function.
	(decay_conversion): Use it.
	
	PR c++/15625
	* pt.c (tsubst_decl): Set DECL_FRIEND_CONTEXT for instantiated
	templates.
	
	PR c++/15629
	* name-lookup.c (arg_assoc_class): Do not find template
	specializations.
	
	PR c++/15209
	* tree.c (lvalue_p_1): Only consider the right-hand side of "."
	expressions when determining whether or not an express is packed.
	
	PR c++/15742
	* g++.dg/warn/Wreturn-1.C: New test.
	
	PR c++/15696
	* g++.dg/expr/ptrmem5.C: New test.
	
	PR c++/15625
	* g++.dg/template/friend27.C: New test.
	
	PR c++/15629
	* g++.dg/template/friend28.C: New test.
	* g++.dg/template/friend.C: Do not depend on <iostream>.  Add
	error message.
	
	PR c++/15209
	* g++.dg/ext/packed3.C: Remove bogus error.
	* g++.dg/ext/packed4.C: Remove bogus check.
	* g++.dg/ext/packed6.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/call.c.diff?cvsroot=gcc&r1=1.476&r2=1.477
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cp-tree.h.diff?cvsroot=gcc&r1=1.969&r2=1.970
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cvt.c.diff?cvsroot=gcc&r1=1.156&r2=1.157
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/name-lookup.c.diff?cvsroot=gcc&r1=1.56&r2=1.57
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&r1=1.856&r2=1.857
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/tree.c.diff?cvsroot=gcc&r1=1.374&r2=1.375
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/typeck.c.diff?cvsroot=gcc&r1=1.547&r2=1.548
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/expr/ptrmem5.C.diff?cvsroot=gcc&r1=1.1&r2=1.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed6.C.diff?cvsroot=gcc&r1=1.1&r2=1.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed3.C.diff?cvsroot=gcc&r1=1.1&r2=1.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed4.C.diff?cvsroot=gcc&r1=1.1&r2=1.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend27.C.diff?cvsroot=gcc&r1=1.1&r2=1.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend28.C.diff?cvsroot=gcc&r1=1.1&r2=1.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend.C.diff?cvsroot=gcc&r1=1.5&r2=1.6
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/warn/Wreturn-1.C.diff?cvsroot=gcc&r1=1.1&r2=1.2


------- Comment #6 From Mark Mitchell 2004-05-31 21:29 -------
Fixed in GCC 3.4.1.

First Last Prev Next    No search results available      Search page      Enter new bug