[Bug c++/30822] wrong choice of overloaded template functions in recursive call

2007-05-17 Thread Zarathustra at gentlemansclub dot de


--- Comment #7 from Zarathustra at gentlemansclub dot de  2007-05-17 13:27 
---
According to my current understanding, the compiler is right not to accept the
given example code:
Name resolution at the point of instantiation does only work for dependent 
names.
Given a expression which looks like
postfix-expression ( expression-listopt )
postfix-expression is a dependent name if (and only if) some thing in 
expression-listopt depends on a template parameter and postfix-expression 
is an identifier. This holds for foo(...) but it does not hold for 
foo...(...) or ::foo(...). Therefore I assume the compiler behaves 
correctly. This is probably another case where the C++ standard is somehow
counterintuitive.


-- 

Zarathustra at gentlemansclub dot de changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution||INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822



[Bug c++/30822] wrong choice of overloaded template functions in recursive call

2007-03-09 Thread Zarathustra at gentlemansclub dot de


--- Comment #6 from Zarathustra at gentlemansclub dot de  2007-03-09 12:35 
---
(In reply to comment #5)
 So, the way I read this is that gcc3.3 and icc9.0 agree that the call is
 ambiguous. I must admit that I don't know whether this is the correct
 behavior.
Also the SunCC yields the ambiguity message. I think in all such cases the
compilers do not implement all rules for the look up of template names as given
by the standard. Probably starting from version 3.4.0 of gcc the error message
changes.

Perhaps it is worth taking a look at the following code:
One template argument is left away, and some  are added.
foo2 is accepted, foo3 is not! From this I assume that there is some problem
with the implementation of the argument-dependent lookup (ADP) in gcc. Does
anyone have any other assumptions?

struct cons_end {};

templatetypename U,typename V struct cons {
 U elem;
 V tail;
};

templatetypename U, typename V
void foo2(U elem, V tail)
{
 foo2(tail.elem,tail.tail);
}

templatetypename U
void foo2(U elem, cons_end tail)
{}

templatetypename U, typename V
void foo3(U elem, V tail)
{
 foo3(tail.elem,tail.tail); // -- the difference is here ( added)
}

templatetypename U
void foo3(U elem, cons_end tail)
{}

int main()
{
 consint,consint,cons_end  list;
 foo2(list.elem,list.tail);
 foo2(list.elem,list.tail);
 foo3(list.elem,list.tail);
}

The error message (from gcc 4.1.2 and gcc 4.3):
test_gccbug.cpp: In function void foo3(U, V) [with U = int, V = cons_end]:
test_gccbug.cpp:32:   instantiated from void foo3(U, V) [with U = int, V =
consint, cons_end]
test_gccbug.cpp:44:   instantiated from here
test_gccbug.cpp:32: error: struct cons_end has no member named elem
test_gccbug.cpp:32: error: struct cons_end has no member named tail

Volker


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822



[Bug c++/30822] wrong choice of overloaded template functions in recursive call

2007-03-08 Thread bangerth at dealii dot org


--- Comment #5 from bangerth at dealii dot org  2007-03-09 04:14 ---
Here's a reduced code:
-
struct cons_end {};

templatetypename U,typename V struct cons {
U elem;
V tail;
};

templateclass T,typename U, typename V
void foo(U elem, V tail)
{
  fooT(tail.elem,tail.tail);
}

templateclass T,typename U
void foo(U elem, cons_end tail)
{}

int main()
{
  consint,consint,cons_end  list;
  fooint(list.elem,list.tail);
}


With gcc3.3, we get this error:

tmp/g c++ -c x.cc
x.cc: In function `void foo(U, V) [with T = int, U = int, V = consint, 
   cons_end]':
x.cc:21:   instantiated from here
x.cc:11: error: call of overloaded `foo(int, cons_end)' is ambiguous
x.cc:10: error: candidates are: void foo(U, V) [with T = int, U = int, V = 
   cons_end]
x.cc:16: error: void foo(U, cons_end) [with T = int, U = int]


On the other hand, gcc 4.1 produces this:
g/x c++ -c x.cc
x.cc: In function 'void foo(U, V) [with T = int, U = int, V = cons_end]':
x.cc:11:   instantiated from 'void foo(U, V) [with T = int, U = int, V =
consint, cons_end]'
x.cc:21:   instantiated from here
x.cc:11: error: 'struct cons_end' has no member named 'elem'
x.cc:11: error: 'struct cons_end' has no member named 'tail'


Finally, icc gives me this:
tmp/g icc -c x.cc
x.cc(21): warning #592: variable list is used before its value is set
fooint(list.elem,list.tail);
 ^

x.cc(11): error: more than one instance of overloaded function foo matches
the argument list:
function template fooT,U,V(U, V)
function template fooT,U(U, cons_end)
argument types are: (int, cons_end)
fooT(tail.elem,tail.tail);
^
  detected during instantiation of void fooT,U,V(U, V) [with T=int,
U=int, V=consint, cons_end] 

compilation aborted for x.cc (code 2)


So, the way I read this is that gcc3.3 and icc9.0 agree that the call is
ambiguous. I must admit that I don't know whether this is the correct
behavior.

On the other hand, gcc4.1 appears to not find an ambiguity, then goes on to
unconditionally call the first function and there hits onto a problem.

W.


-- 

bangerth at dealii dot org changed:

   What|Removed |Added

 CC||bangerth at dealii dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822



[Bug c++/30822] wrong choice of overloaded template functions in recursive call

2007-02-21 Thread Zarathustra at gentlemansclub dot de


--- Comment #4 from Zarathustra at gentlemansclub dot de  2007-02-21 10:16 
---
Now the code was also compiled with 4.3.0 and produced the same error message.

I can make the actual failure more specific: The following code compiles fine:

templatetemplatetypename class TOperator,typename TElement
void for_all_5(TElement elem, cons_end tail);

templatetemplatetypename class TOperator,typename TElement, typename TTail
void for_all_5(TElement elem, TTail tail)
{
  TOperatorTElement()(elem);
  for_all_5TOperator(tail.elem,tail.tail);
}

templatetemplatetypename class TOperator,typename TElement
void for_all_5(TElement elem, cons_end tail)
{
  TOperatorTElement()(elem);
}

// -- snip -- //
in main:
for_all_5op(list.elem,list.tail);

The difference is the forward declaration of the second for_all method.
From my understanding of the standard it is not necessary to do the forward
declaration since by 14.6.4/1 declarations which are visible at the point of
instantiation are to be considered and by 14.6.4.1/1 the point of 
instantiation of all template functions is at the definition of the main
function.


-- 

Zarathustra at gentlemansclub dot de changed:

   What|Removed |Added

Version|4.1.2   |4.3.0


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822



[Bug c++/30822] wrong choice of overloaded template functions in recursive call

2007-02-20 Thread Zarathustra at gentlemansclub dot de


--- Comment #3 from Zarathustra at gentlemansclub dot de  2007-02-21 07:44 
---
The same problem appears with gcc 4.1.2 20061115 (prerelease) (SUSE Linux)


-- 

Zarathustra at gentlemansclub dot de changed:

   What|Removed |Added

Version|4.1.1   |4.1.2


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822



[Bug c++/30822] wrong choice of overloaded template functions in recursive call

2007-02-16 Thread pinskia at gcc dot gnu dot org


--- Comment #1 from pinskia at gcc dot gnu dot org  2007-02-16 15:47 ---
// now the order changed and the compiler complains!

I think GCC 4.1.x and above are doing the correct behavior with respect of the
C++ standard.  The C++ standard has specific rules about namelookup in
templates which differs from what most people think they are as before GCC
4.1.x did not implement them and I think Microsoft's VS also still does not
implement them.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822



[Bug c++/30822] wrong choice of overloaded template functions in recursive call

2007-02-16 Thread Zarathustra at gentlemansclub dot de


--- Comment #2 from Zarathustra at gentlemansclub dot de  2007-02-16 16:35 
---
I know the rules for template function name lookup are complicated, and I do
not claim that I understand them completely. But I am pretty sure that the
order of the definitions should not matter. There is a partial ordering of
template functions to decide which function is used. This ordering depends on
which function is more specialized than the other, but not the sequence of
the definitions.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822