Article View: gnu.g++.bug
Article #1294___ls ( operator << ) not mangled in template
From: jimc
Date: Thu, 17 Dec 1992 02:43
Date: Thu, 17 Dec 1992 02:43
463 lines
9699 bytes
9699 bytes
// BUG13.C -- ___ls ( operator << ) not mangled in template
/* Gnu g++ v2.3.2 for SPARC-SunOS v4.1.1
A compilation unit contains two template classes each of which has a
non-friend operator << template function to print it out. Both of
these are given the unmangled name ___ls. The assembler (not to
mention the linker, were the compilations separate) doesn't like this.
The names ___ls are used appropriately both at the point of call and
the point of definition, such that if the second one is commented out,
the code will compile and execute correctly.
If the operator <<'s are declared in the template classes to be friends,
the names are generated correctly. 99.9% of operator <<'s are friends,
and it was only chance and laziness that led me to omit the friend
declaration thereby happening to discover this bug.
James F. Carter Voice 310 825 2897 FAX 310 206 6673
UCLA-Mathnet; 6221 MSA; 405 Hilgard Ave.; Los Angeles, CA, USA 90024-1555
Internet: jimc@math.ucla.edu BITNET: jimc%math.ucla.edu@INTERBIT
UUCP:...!{ucsd,ames,ncar,gatech,purdue,rutgers,decvax,uunet}!math.ucla.edu!jimc
*/
#include <stdlib.h>
#include <iostream.h>
template <class T> struct list { //Also acts as a list node and as root
public:
list* forw;
T* data;
list(T* d = NULL) : forw(NULL), data(d) { }
void operator += (list& n)
{ n.forw = forw; forw = &n; }
list* next() const
{ return forw; }
//Fails only if operator << is non-friendly
// friend ostream& operator << (ostream& f, const list& s);
};
template<class X, class Y> struct pair{
typedef X pX; //Add typedefs
typedef Y pY;
X x;
Y y;
pair(const X& xi, const Y& yi) : x(xi), y(yi) { }
//Fails only if operator << is non-friendly
// friend ostream& operator << (ostream& f, const pair& s);
};
template <class P> struct list_of_pairs {
list<P> data;
list_of_pairs(P* pi = NULL) : data(pi) { }
void operator += (P& pi) {
data += *(new list<P>(&pi));
}
};
// Fails with this template in place. To see it work, comment this out.
template<class X, class Y>
ostream& operator << (ostream& f, const pair<X,Y>& p) {
return f << '(' << p.x << ' ' << p.y << ')';
}
template <class T> ostream& operator << (ostream& f, const list<T>& s) {
for (const list<T>* p = &s; p; p = p->next()) {
T* dp = p->data;
if (dp)
f << *dp; //Use this to see it fail
// f << '(' << dp->x << ' ' << dp->y << ')'; //Use to see it work
else f << "NULL";
}
return f;
}
typedef int X; //The purpose of all this is to do something
typedef double Y; //complicated with typedefs of template classes.
typedef pair<X,Y> PXY;
list_of_pairs<PXY> lp;
int main() {
int x;
double y;
for (x = 0; x < 4; ++x) {
lp += *(new pair<int,double>(x, x+0.5));
cout << lp.data << '\n';
}
}
/*
-------- Assembly code output -- annotated
gcc2_compiled.:
typedef pair<X,Y> PXY;
list_of_pairs<PXY> lp;
double LC0(0.5)
LC0: .double 0r0.5
int main() {
int x; %fp-20
double y; %fp-40 (?)
for (x = 0; x < 4; ++x) { (to L229)
lp += *(new pair<int,double>(x, x+0.5));
___t4pair2ZiZdRCiRCd(x, x+0.5) //pair<int,double>(con int&, con dbl&)
___apl__t13list_of_pairs1Zt4pair2ZiZdRt4pair2ZiZd,0
// list_of_pairs<pair<int,dbl>>::op+= (pair<int,dbl>&)
cout << lp.data << '\n';
___ls__FR7ostreamc(___ls (cout, lp.data) , '\n')
// ___ls__FR7ostreamc = ::op << (ostream&, char)
// ___ls, what the hell is this? ==========
}
}
// First instance of ___ls: ==========
(ostream& f, // in %fp+68
const list<T>& s) { // in %fp+72,
for (const list<T>* p = &s; p; p = p->next()) {
// p in %fp-20, end of loop at L233
T* dp = p->data; // dp in %fp-24
if (dp) // Zero code at L235
___ls(f, *dp) // Which ___ls is this supposed to be? =======
else
___ls__FR7ostreamPCc(f, "NULL")
// ___ls__FR7ostreamPCc = ::op << (ostream, const char*)
}
}
___apl__t13list_of_pairs1Zt4pair2ZiZdRt4pair2ZiZd:
(analysis omitted; it seems to work)
___t13list_of_pairs1Zt4pair2ZiZdPt4pair2ZiZd:
(analysis omitted; it seems to work)
_next__Ct4list1Zt4pair2ZiZd:
(analysis omitted; it seems to work)
___apl__t4list1Zt4pair2ZiZdRT0:
(analysis omitted; it seems to work)
___t4list1Zt4pair2ZiZdPt4pair2ZiZd:
(analysis omitted; it seems to work)
___t4pair2ZiZdRCiRCd:
(analysis omitted; it seems to work)
Second instance of ___ls: ===========
(ostream& f, // in %fp+68
const pair<X,Y>& p) { // in %fp+72,
call ___ls__FR7ostreamc,0 (f, '(')
call ___ls__FR7ostreami,0 (previous, p.x) x is int
call ___ls__FR7ostreamc,0 (previous, ' ')
call ___ls__FR7ostreamd,0 (previous, p.y) y is double
call ___ls__FR7ostreamc,0 (previous, ')')
}
__GLOBAL_$I$lp: (constructor of global object lp)
call ___t13list_of_pairs1Zt4pair2ZiZdPt4pair2ZiZd,0
--------------------- Actual assembly code
gcc2_compiled.:
.global _lp
.data
.align 4
_lp:
.skip 8
.align 8
LC0:
.double 0r0.5
.text
.align 4
.global _main
.proc 04
_main:
!#PROLOGUE# 0
save %sp,-160,%sp
!#PROLOGUE# 1
call ___main,0
nop
st %g0,[%fp-20]
L228:
ld [%fp-20],%o0
cmp %o0,3
bg L229
nop
mov 16,%o0
call ___builtin_new,0
nop
add %fp,-20,%o1
ld [%fp-20],%f2
fitod %f2,%f0
sethi %hi(LC0),%o2
ldd [%o2+%lo(LC0)],%f2
faddd %f0,%f2,%f0
std %f0,[%fp-40]
add %fp,-40,%o2
call ___t4pair2ZiZdRCiRCd,0
nop
mov %o0,%l0
sethi %hi(_lp),%o1
or %o1,%lo(_lp),%o0
mov %l0,%o1
call ___apl__t13list_of_pairs1Zt4pair2ZiZdRt4pair2ZiZd,0
nop
sethi %hi(_cout),%o1
or %o1,%lo(_cout),%o0
sethi %hi(_lp),%o2
or %o2,%lo(_lp),%o1
call ___ls,0
nop
mov %o0,%o1
mov %o1,%o0
mov 10,%o1
call ___ls__FR7ostreamc,0
nop
L230:
ld [%fp-20],%o0
add %o0,1,%o1
st %o1,[%fp-20]
b L228
nop
L229:
mov 0,%i0
b L227
nop
b L227
nop
L227:
ret
restore
.align 8
LC1:
.ascii "NULL\0"
.align 4
.proc 0110
___ls:
!#PROLOGUE# 0
save %sp,-120,%sp
!#PROLOGUE# 1
st %i0,[%fp+68]
st %i1,[%fp+72]
ld [%fp+72],%o0
st %o0,[%fp-20]
L232:
ld [%fp-20],%o0
cmp %o0,0
be L233
nop
ld [%fp-20],%o0
ld [%o0+4],%o1
st %o1,[%fp-24]
ld [%fp-24],%o0
cmp %o0,0
be L235
nop
ld [%fp+68],%o0
ld [%fp-24],%o1
call ___ls,0
nop
b L234
nop
L235:
ld [%fp+68],%o0
sethi %hi(LC1),%o2
or %o2,%lo(LC1),%o1
call ___ls__FR7ostreamPCc,0
nop
L236:
L234:
ld [%fp-20],%o0
call _next__Ct4list1Zt4pair2ZiZd,0
nop
st %o0,[%fp-20]
b L232
nop
L233:
ld [%fp+68],%i0
b L231
nop
b L231
nop
L231:
ret
restore
.align 4
.proc 020
___apl__t13list_of_pairs1Zt4pair2ZiZdRt4pair2ZiZd:
!#PROLOGUE# 0
save %sp,-112,%sp
!#PROLOGUE# 1
mov %i0,%l0
st %i1,[%fp+72]
mov 8,%o0
call ___builtin_new,0
nop
mov %o0,%o1
mov %o1,%o0
ld [%fp+72],%o1
call ___t4list1Zt4pair2ZiZdPt4pair2ZiZd,0
nop
mov %o0,%l1
mov %l0,%o0
mov %l1,%o1
call ___apl__t4list1Zt4pair2ZiZdRT0,0
nop
L237:
ret
restore
.align 4
.proc 0110
___t13list_of_pairs1Zt4pair2ZiZdPt4pair2ZiZd:
!#PROLOGUE# 0
save %sp,-112,%sp
!#PROLOGUE# 1
mov %i0,%l0
st %i1,[%fp+72]
mov %l0,%o0
ld [%fp+72],%o1
call ___t4list1Zt4pair2ZiZdPt4pair2ZiZd,0
nop
L239:
mov %l0,%i0
b L238
nop
b L238
nop
L238:
ret
restore
.align 4
.proc 0110
_next__Ct4list1Zt4pair2ZiZd:
!#PROLOGUE# 0
save %sp,-112,%sp
!#PROLOGUE# 1
mov %i0,%o0
ld [%o0],%i0
b L240
nop
b L240
nop
L240:
ret
restore
.align 4
.proc 020
___apl__t4list1Zt4pair2ZiZdRT0:
!#PROLOGUE# 0
save %sp,-112,%sp
!#PROLOGUE# 1
mov %i0,%o0
st %i1,[%fp+72]
ld [%fp+72],%o1
ld [%o0],%o2
st %o2,[%o1]
ld [%fp+72],%o1
st %o1,[%o0]
L241:
ret
restore
.align 4
.proc 0110
___t4list1Zt4pair2ZiZdPt4pair2ZiZd:
!#PROLOGUE# 0
save %sp,-112,%sp
!#PROLOGUE# 1
mov %i0,%o0
st %i1,[%fp+72]
st %g0,[%o0]
ld [%fp+72],%o1
st %o1,[%o0+4]
L243:
mov %o0,%i0
b L242
nop
b L242
nop
L242:
ret
restore
.align 4
.proc 0110
___t4pair2ZiZdRCiRCd:
!#PROLOGUE# 0
save %sp,-112,%sp
!#PROLOGUE# 1
mov %i0,%o0
st %i1,[%fp+72]
st %i2,[%fp+76]
ld [%fp+72],%o1
ld [%o1],%o2
st %o2,[%o0]
ld [%fp+76],%o1
ldd [%o1],%o2
std %o2,[%o0+8]
L245:
mov %o0,%i0
b L244
nop
b L244
nop
L244:
ret
restore
.align 4
.proc 0110
___ls:
!#PROLOGUE# 0
save %sp,-120,%sp
!#PROLOGUE# 1
st %i0,[%fp+68]
st %i1,[%fp+72]
ld [%fp+68],%o0
mov 40,%o1
call ___ls__FR7ostreamc,0
nop
ld [%fp+72],%o1
ld [%o1],%o1
call ___ls__FR7ostreami,0
nop
mov %o0,%o1
mov %o1,%o0
mov 32,%o1
call ___ls__FR7ostreamc,0
nop
ld [%fp+72],%o1
ldd [%o1+8],%f0
std %f0,[%fp-24]
ld [%fp-24],%o1
ld [%fp-20],%o2
call ___ls__FR7ostreamd,0
nop
mov %o0,%o1
mov %o1,%o0
mov 41,%o1
call ___ls__FR7ostreamc,0
nop
mov %o0,%i0
b L246
nop
b L246
nop
L246:
ret
restore
.align 4
.global __GLOBAL_$I$lp
.proc 020
__GLOBAL_$I$lp:
!#PROLOGUE# 0
save %sp,-112,%sp
!#PROLOGUE# 1
sethi %hi(_lp),%o1
or %o1,%lo(_lp),%o0
mov 0,%o1
call ___t13list_of_pairs1Zt4pair2ZiZdPt4pair2ZiZd,0
nop
L247:
ret
restore
*/
Technical Details
Message-ID:
<9212171843.AA26474@malibu.pic.ucla.edu>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!pic.ucla.edu!jimcShow Full Headers
Complete Article Headers
Newsgroups: gnu.g++.bug Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!pic.ucla.edu!jimc From: jimc@pic.ucla.edu Subject: ___ls ( operator << ) not mangled in template Message-ID: <9212171843.AA26474@malibu.pic.ucla.edu> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Thu, 17 Dec 1992 02:43:02 GMT Approved: bug-g++@prep.ai.mit.edu Lines: 464