Bug 9602 - [3.2/3.3/3.4 regression] Total confusion about template/friend/virtual/abstract
|
Bug#:
9602
|
Product: gcc
|
Version: 3.2
|
|
Host:
|
Target:
|
Build:
|
|
Status: RESOLVED
|
Severity: critical
|
Priority: P1
|
|
Resolution: FIXED
|
Assigned To: lerdsuwa@gcc.gnu.org
|
Reported By: vil@rccp.tsukuba.ac.jp
|
|
Component: c++
|
Target Milestone: ---
|
|
Summary: [3.2/3.3/3.4 regression] Total confusion about template/friend/virtual/abstract
|
|
Keywords: rejects-valid
|
|
Opened: 2003-02-06 21:26
|
Fails to compile code which was legal under 2.96, does not include any of the
patterns in the known-bugs list.
Refuses to instantiate a template class on the grounds that it has abstract
functions, when in fact the functions concerned are not even virtual
Release:
g++ -v Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.2/specs
Configured with: ../configure --prefix=/usr --libdir=/usr/lib
--with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info
--enable-shared --enable-thr
Environment:
uname -a
Linux localhost.localdomain 2.4.19-16mdk #1 Fri Sep 20 18:15:05 CEST 2002 i686
unknown unknown GNU/Linux
How-To-Repeat:
g++ yum.C
Unformatted:
eads=posix --disable-checking --enable-long-long --enable-__cxa_atexit
--enable-languages=c,c++,ada,f77,objc,java --host=i586-mandrake-linux-gnu
--with-system-zlib Thread model: posix gcc version 3.2 (Mandrake Linux 9.0
3.2-1mdk)
State-Changed-From-To: open->feedback
State-Changed-Why: For some reason, the testcase didn't make it into the
report. Can you try to send it to me so that I can attach
it to the report?
Thanks
Wolfgang
From: Victor Isaac Lesk <vil@rccp.tsukuba.ac.jp>
To: <bangerth@dealii.org>, <gcc-bugs@gcc.gnu.org>, <gcc-prs@gcc.gnu.org>,
<nobody@gcc.gnu.org>, <vil@rccp.tsukuba.ac.jp>, <gcc-gnats@gcc.gnu.org>
Cc:
Subject: Re: c++/9602: falsely concludes that function defined within class
body is virtual and abstract, therefore compiler fails to allow class
instantiation with pure virtual function error.
Date: Fri, 7 Feb 2003 11:22:12 +0900 (JST)
On 6 Feb 2003 bangerth@dealii.org wrote:
> Synopsis: falsely concludes that function defined within class body is virtual and abstract, therefore compiler fails to allow class instantiation with pure virtual function error.
>
> State-Changed-From-To: open->feedback
> State-Changed-By: bangerth
> State-Changed-When: Thu Feb 6 23:23:46 2003
> State-Changed-Why:
> For some reason, the testcase didn't make it into the
> report. Can you try to send it to me so that I can attach
> it to the report?
>
> Thanks
> Wolfgang
>
> http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=9602
>
Here it is:
//////////////
#include<iostream>
#include<stdio.h>
using namespace std;
template<typename t>
class Pair
{
private:
protected:
public:
t first;
t second;
t&last;
Pair();
Pair(t,t);
Pair(const string);
void set_Pair(const t,const t);
void set(const t,const t);
void set_First(const t);
void set_Second(const t);
void set_Last(const t);
t get_First(void)const;
t get_Second(void)const;
t get_Last(void)const;
bool contains(const t)const;
bool includes(const t)const;
void display(void)const;
void operator=(const Pair<t>);
template<typename l>operator class Pair<l>(void)const;
friend ostream&operator<<(ostream&a,const class Pair<t>&r)
{
return a<<r.first<<SPC<<r.second;
}
friend istream&operator>>(istream&a,class Pair<t>&r)
{
return a>>r.first>>r.second;
}
};
template<typename t>
ostream&
operator<<(ostream&,const Pair<t>&);
template<typename t>
istream&
operator>>(istream&,Pair<t>&);
template<typename t>
Pair<t>::
Pair():
last(second)
{
}
template<typename t>
Pair<t>::
Pair(const string s):
last(second)
{
}
template<typename t>
Pair<t>::
Pair(t a,t b):
last(second)
{
set_Pair(a,b);
}
template<typename t>
t
Pair<t>::
get_First(void)const
{
return first;
}
template<typename t>
t
Pair<t>::
get_Second(void)const
{
return second;
}
template<typename t>
t
Pair<t>::
get_Last(void)const
{
return last;
}
template<typename t>
void
Pair<t>::
set(t l,t h)
{
first=l;second=h;
}
template<typename t>
void
Pair<t>::
operator=(const Pair<t> pair)
{
set_First(pair.first);
set_Second(pair.second);
}
template<typename t>
void
Pair<t>::
set_Pair(t l,t h)
{
set(l,h);
}
template<typename t>
void
Pair<t>::
set_First(const t a)
{
first=a;
}
template<typename t>
void
Pair<t>::
set_Second(const t a)
{
second=a;
}
template<typename t>
bool
Pair<t>::
contains(const t a)const
{
return (a==first || a==second);
}
template<typename t>
bool
Pair<t>::
includes(const t a)const
{
return contains(a);
}
template<typename t>
void
Pair<t>::
display(void)const
{
cout<<LPR<<first<<COM<<second<<RPR;
}
template<typename t>template<typename l>
Pair<t>::
operator Pair<l>(void)const
{
return Pair<l>(l(first),l(second));
}
int main(const int,const char*const*const)
{
Pair<int> pair1;
return 0;
}
State-Changed-From-To: feedback->analyzed
State-Changed-Why: Confirmed. This is a smaller testcase:
---------------------------
template <typename T> struct X {
void foo (X);
friend void bar () {}
};
template <typename T>
void X<T>::foo (X x) {}
template struct X<int>;
-----------------------------
There seems to be profound confusion within the compiler
about something, since it says
tmp/g> /home/bangerth/bin/gcc-3.2/bin/gcc -c x.cc
x.cc:7: cannot declare parameter `x' to be of type `X<T>'
x.cc:7: because the following virtual functions are abstract:
x.cc:3: void bar()
This is, of course, entirely bogus.
It worked with 3.0, but is broken with present 3.2.2, 3.3
and 3.4 branches, so it's a regression. The testcase is
so simple that I can't believe that this is something
that hasn't come up yet. Hopefully it's simple to fix.
From playing around, it seems to have to do with the fact
that the friend function is not only declared, but also
defined inside the class; it is instantiated at the place
of first use, which is where the error is displayed.
W.
Responsible-Changed-From-To: unassigned->lerdsuwa
Responsible-Changed-Why: Figured out what's wrong.
State-Changed-From-To: analyzed->closed
State-Changed-Why: Fixed.