This is the mail archive of the gcc-prs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

libstdc++/10448: Bug in dynamic_cast algorithm


>Number:         10448
>Category:       libstdc++
>Synopsis:       Bug in dynamic_cast algorithm
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Apr 22 01:06:01 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     sunil dot k dot davasam at intel dot com
>Release:        unknown-1.0
>Organization:
>Environment:
UnitedLinux 1.0 (ia64)
>Description:
There is a bug in dynamic_cast algorithm.  Based on ABI document, the function __dynamic_cast () takes 4 arguments.

Here is prototype:

extern "C" void* __dynamic_cast ( const void *sub, const abi:: __class_type_info *src, const abi::__class_type_info *dst, std::ptrdiff_t src2dst_offset );

The 4th argument "src2dst_offset" is a static hint about the location of the source subobject with respect to the complete object;

special negative values for 4th argument are:

    -1 : no hint
    -2 : src is not a public base of dst
    -3 : src is a multiple public base type but never a virtual base type.

Gcc compiler generates "-2" for 4th argument for the attached testcase. The testcase passes ,if you just compile and run. But, it fails when we change the value of 4th argument for __dynamic_cast() function from "-2" to "-1". Basically, If we don't provide any hint to dynamic_cast algorithm, it doesn't work properly atleast for this testcase.

   I don't know whether gcc compiler generates "-1" for any case, but this is an interoperability problem. Because, if some other compiler generates "-1" and link with gcc libraries, the application gives wrong output or sometimes segmentation fault.
>How-To-Repeat:
cmd>  g++ -v
Reading specs from /usr/lib/gcc-lib/ia64-suse-linux/3.2/specs
Configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --enable-languages=c,c++,f77,objc,java,ada --enable-libgcj --with-gxx-include-dir=/usr/include/g++ --with-slibdir=/lib --with-system-zlib --enable-shared --enable-__cxa_atexit ia64-suse-linux
Thread model: posix
gcc version 3.2

cmd> g++ tt.cpp
cmd> a.out
C3()
C2()
C3()
C2()
C3()
C2()
Catching bad_cast Exception.

cmd> g++ -S tt.cpp
Open the file tt.s and change the 4th argument of __dynamic_cast() function from "-2" to "-1"

cmd> g++ tt.s
cmd> a.out
C3()
C2()
C3()
C2()
C3()
C2()

>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="tt.cpp"
Content-Disposition: inline; filename="tt.cpp"

#include <stdio.h>
#include <exception>
#include <typeinfo>

struct C11
{
	virtual int f1()	{ return 11; }

	virtual ~C11() { 
		printf("%sC%d()\n", "~", 11);
	}

	C11() { 
		printf("%sC%d()\n", "", 11);
	}
};

struct C3
{
	virtual int f4()	{ return 3; }
	virtual int f2()	{ return 3; }
//	int i;

	C3() { 
		printf("%sC%d()\n", "", 3);
	}
};

struct C2: virtual C3
{
	C2() { 
		printf("%sC%d()\n", "", 2);
	}
};

C2 x2_3(C11 *ptrC11)
{

	C2 tmp_C2;

	tmp_C2 = dynamic_cast<C2 &>(*ptrC11);

	return tmp_C2;
}

int main()
{
	try {
		C2 ref_obj2, tmp_ref_obj2;
		C11 *tmp_ref_ptrC11;

		tmp_ref_ptrC11 = (C11 *)&ref_obj2;
		tmp_ref_obj2 = x2_3(tmp_ref_ptrC11);

	} catch(std::bad_cast) {
		printf("Catching bad_cast Exception.\n");
	}

	return 0;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]