From: scstech@solomon.technet.sg (Fong Khai Yin)
Subject: g++ 2.2.2 - bug in temp obj as function args ??
Organization: Singapore Computer Systems Ltd
Distribution: gnu
Date: Thu, 1 Oct 1992 05:25:47 GMT

I think there is a bug in g++ 2.2.2 where an object is used as an argument to a function
that is expecting a char*.
Please correct me if this is incorrect.

Is it possible to get a patch for this problem ???


The problem is in the temporary object used as the function's argument.
I tested the code with SUN 2.1 C++ and g++ 2.2.2.

The result :-

Sun 2.1 C++ :
myString constructor : char*; str=this is to test compiler
myString constructor : myString; str=this is to test compiler
fun2; str=this is to test compiler
myString destructor : mystr=this is to test compiler
myString destructor : mystr=this is to test compiler

g++ 2.2.2 :
myString constructor : char*; str=this is to test compiler
myString constructor : myString; str=this is to test compiler
myString destructor : mystr=this is to test compiler
fun2; str=this is to test compiler
myString destructor : mystr=this is to test compiler


The temporary object was destructed before execution of 'fun2' 

Enclosed below are the code for this test and the assembly code generated by Sun 2.1 C++ and g++ 2.2.2.

Thank in advance.
Joel


Example :

// ------------- supporting class ---------------------------

#include <stdio.h>
#include <string.h>

class myString {
private:
	char	mystr[1000];

public:
		myString();
		myString( char* );
		myString( myString& );

		~myString();

	myString&	operator=( char* );
	myString&	operator=( myString );
			operator char*();
};


#include <stdio.h>
#include "myString.h"

myString::myString()
{
	printf( "myString constructor : default\n" );
}


myString::myString( char* str )
{
	strcpy( mystr, str );
	printf( "myString constructor : char*; str=%s\n", str );
}

myString::myString( myString& str )
{
	strcpy( mystr, ( char* )str );
	printf( "myString constructor : myString; str=%s\n", (char*)str );
}

myString::~myString()
{
	printf( "myString destructor : mystr=%s\n", mystr );
}

myString&
myString::operator=( char* str )
{
	strcpy( mystr, str );
	return *this;
}

myString&
myString::operator=( myString str )
{
	strcpy( mystr, ( char* )str );
	return *this;
}

myString::operator char*()
{
	return mystr;
}


// ------------------- testing routines -----------------------

#include "myString.h"

myString
fun_return()
{
	static myString mystr( "this is to test compiler" );
	return mystr;
}


void
fun1( myString str )
{
	printf( "arg str = %s\n", (char*)str );
}

void
fun2( char* str )
{
	printf( "fun2; str=%s\n", str );
}

main()
{
	fun2( fun_return() );
}

===================== Assembly code generated by SUN C++ 2.1 ===================


LL0:
	.seg	"data"
	.align	4
___0__F1:
	.word	0x0
	.seg	"text"
	.proc 02
	.global	_fun_return__Fv
_fun_return__Fv:
	!#PROLOGUE# 0
	sethi	%hi(LF23),%g1
	add	%g1,%lo(LF23),%g1
	save	%sp,%g1,%sp
	!#PROLOGUE# 1
	st	%i0,[%fp+0x44]
	.seg	"bss"
L25:	.skip	1000
	.seg	"text"
	.seg	"data1"
L26:
	.ascii	"this is to test compiler\0"
	.seg	"text"
	sethi	%hi(___0__F1),%o0
	ld	[%o0+%lo(___0__F1)],%o0
	tst	%o0
	be	L2000000
	nop
	mov	0,%o1
	b	L2000001
	nop
L2000000:
	set	L25,%o0
	set	L26,%o1
	call	___ct__8myStringFPc,2
	nop
	set	L25,%o1
	sethi	%hi(___0__F1),%o2
	st	%o1,[%o2+%lo(___0__F1)]
L2000001:
	ld	[%fp+0x44],%o0
	set	L25,%o1
	call	___ct__8myStringFR8myString,2
	nop
	b	LE23
	nop
LE23:
	ret
	restore
       LF23 = -96
	LP23 = 96
	LST23 = 96
	LT23 = 96
	.seg	"data"
	.seg	"text"
	.proc 02
	.global	_fun1__F8myString
_fun1__F8myString:
	!#PROLOGUE# 0
	sethi	%hi(LF30),%g1
	add	%g1,%lo(LF30),%g1
	save	%sp,%g1,%sp
	!#PROLOGUE# 1
	st	%i0,[%fp+0x44]
	.seg	"data1"
L32:
	.ascii	"arg str = %s\012\0"
	.seg	"text"
	ld	[%fp+0x44],%o0
	call	___opPc__8myStringFv,1
	nop
	mov	%o0,%o1
	set	L32,%o0
	call	_printf,2
	nop
LE30:
	ret
	restore
       LF30 = -96
	LP30 = 96
	LST30 = 96
	LT30 = 96
	.seg	"data"
	.seg	"text"
	.proc 02
	.global	_fun2__FPc
_fun2__FPc:
	!#PROLOGUE# 0
	sethi	%hi(LF34),%g1
	add	%g1,%lo(LF34),%g1
	save	%sp,%g1,%sp
	!#PROLOGUE# 1
	st	%i0,[%fp+0x44]
	.seg	"data1"
L36:
	.ascii	"fun2; str=%s\012\0"
	.seg	"text"
	set	L36,%o0
	ld	[%fp+0x44],%o1
	call	_printf,2
	nop
LE34:
	ret
	restore
       LF34 = -96
	LP34 = 96
	LST34 = 96
	LT34 = 96
	.seg	"data"
	.seg	"text"
	.proc 04
	.global	_main
_main:
	!#PROLOGUE# 0
	sethi	%hi(LF38),%g1
	add	%g1,%lo(LF38),%g1
	save	%sp,%g1,%sp
	!#PROLOGUE# 1
	call	__main,0
	nop
	sub	%fp,0x3e8,%o0
	call	_fun_return__Fv,1
	nop
	sub	%fp,0x3e8,%o0
	call	___opPc__8myStringFv,1		
	nop
	call	_fun2__FPc,1			<-- fun2 execution
	nop
	sub	%fp,0x3e8,%o0
	mov	0x2,%o1
	call	___dt__8myStringFv,2		<-- destruction of temp. obj.
	nop
LE38:
	ret
	restore
       LF38 = -1096
	LP38 = 96
	LST38 = 96
	LT38 = 96
	.seg	"data"
	.align	4
	.global	___LinkInHead
___LinkInHead:
	.word	___head+0x0
	.seg	"text"
	.proc 02
	.global	___std__fun3_cxx_fun_return_
___std__fun3_cxx_fun_return_:
	!#PROLOGUE# 0
	sethi	%hi(LF44),%g1
	add	%g1,%lo(LF44),%g1
	save	%sp,%g1,%sp
	!#PROLOGUE# 1
	sethi	%hi(___0__F1),%o0
	ld	[%o0+%lo(___0__F1)],%o0
	tst	%o0
	be	L2000002
	nop
	sethi	%hi(___0__F1),%o0
	ld	[%o0+%lo(___0__F1)],%o0
	mov	0x2,%o1
	call	___dt__8myStringFv,2
	nop
	mov	%o0,%o1
	b	L2000003
	nop
L2000002:
	mov	0,%o1
L2000003:
LE44:
	ret
	restore
       LF44 = -96
	LP44 = 96
	LST44 = 96
	LT44 = 96
	.seg	"data"
	.align	4
___link:
	.word	0x0
	.word	0x0
	.word	___std__fun3_cxx_fun_return_+0x0


======================= Assembly code from g++ 2.2.2 ====================

gcc2_compiled.:

	.reserve _mystr.2,1000,"bss"

	.reserve __$tmp_0.3,8,"bss"
.text
	.align 8
LC0:
	.ascii "this is to test compiler\0"
	.align 4
	.global _fun_return__Fv
	.proc	010
_fun_return__Fv:
	!#PROLOGUE# 0
	save %sp,-112,%sp
	!#PROLOGUE# 1
	ld [%fp+64],%l0
	sethi %hi(__$tmp_0.3),%o0
	ld [%o0+%lo(__$tmp_0.3)],%o1
	cmp %o1,0
	bne L2
	nop
	sethi %hi(__$tmp_0.3),%o0
	mov 1,%o1
	st %o1,[%o0+%lo(__$tmp_0.3)]
	sethi %hi(_mystr.2),%o1
	or %o1,%lo(_mystr.2),%o0
	sethi %hi(LC0),%o2
	or %o2,%lo(LC0),%o1
	call ___8myStringPc,0
	nop
L2:
	mov %l0,%o0
	sethi %hi(_mystr.2),%o2
	or %o2,%lo(_mystr.2),%o1
	call ___8myStringRT0,0
	nop
	b,a L1
	b,a L1
	b,a L3
	b,a L1
L3:
L1:
	mov %l0,%i0
	jmp %i7+12
	restore
	.align 8
LC1:
	.ascii "arg str = %s\12\0"
	.align 4
	.global _fun1__FG8myString
	.proc	020
_fun1__FG8myString:
	!#PROLOGUE# 0
	save %sp,-112,%sp
	!#PROLOGUE# 1
	mov %i0,%l0
	mov %l0,%o0
	call ___opPc__8myString,0
	nop
	mov %o0,%o1
	sethi %hi(LC1),%o2
	or %o2,%lo(LC1),%o0
	call _printf,0
	nop
	mov %l0,%o0
	mov 2,%o1
	call __$_8myString,0
	nop
	b,a L6
L4:
	mov %l0,%o0
	mov 2,%o1
	call __$_8myString,0
	nop
	b,a L5
L6:
L5:
	ret
	restore
	.align 8
LC2:
	.ascii "fun2; str=%s\12\0"
	.align 4
	.global _fun2__FPc
	.proc	020
_fun2__FPc:
	!#PROLOGUE# 0
	save %sp,-112,%sp
	!#PROLOGUE# 1
	st %i0,[%fp+68]
	sethi %hi(LC2),%o1
	or %o1,%lo(LC2),%o0
	ld [%fp+68],%o1
	call _printf,0
	nop
	b,a L8
	b,a L7
L8:
L7:
	ret
	restore
	.align 4
	.global _main
	.proc	04
_main:
	!#PROLOGUE# 0
	save %sp,-1136,%sp
	!#PROLOGUE# 1
	call ___main,0
	nop
	add %fp,-1016,%o0
	st %o0,[%sp+64]
	call _fun_return__Fv,0
	nop
	unimp 1000
	add %fp,-1016,%o1
	mov %o1,%o0
	call ___opPc__8myString,0
	nop
	mov %o0,%l0
	add %fp,-1016,%o1
	mov %o1,%o0
	mov 2,%o1
	call __$_8myString,0			<---- destruction of temp. obj.
	nop
	mov %l0,%o0
	call _fun2__FPc,0			<---- fun2 execution
	nop
	mov 0,%i0
	b,a L9
	b,a L9
L9:
	ret
	restore
	.align 4
	.global __GLOBAL_$D$fun_return__Fv
	.proc	020
__GLOBAL_$D$fun_return__Fv:
	!#PROLOGUE# 0
	save %sp,-112,%sp
	!#PROLOGUE# 1
	sethi %hi(__$tmp_0.3),%o0
	ld [%o0+%lo(__$tmp_0.3)],%o1
	cmp %o1,0
	be L11
	nop
	sethi %hi(_mystr.2),%o1
	or %o1,%lo(_mystr.2),%o0
	mov 2,%o1
	call __$_8myString,0
	nop
L11:
	b,a L12
	b,a L10
L12:
L10:
	ret
	restore
	.align 4
	.global __GLOBAL_$I$fun_return__Fv
	.proc	020
__GLOBAL_$I$fun_return__Fv:
	!#PROLOGUE# 0
	save %sp,-112,%sp
	!#PROLOGUE# 1
	b,a L14
	b,a L13

Newsgroups: gnu.g++.bug