From mboxrd@z Thu Jan 1 00:00:00 1970 From: kainz@ilm.com To: gcc-gnats@gcc.gnu.org Cc: hubbard@ilm.com, jyost@ilm.com Subject: libstdc++/4292: dynamic_cast incorrectly returns 0 Date: Mon, 10 Sep 2001 16:06:00 -0000 Message-id: <20010910230511.4023.qmail@sourceware.cygnus.com> X-SW-Source: 2001-09/msg00224.html List-Id: >Number: 4292 >Category: libstdc++ >Synopsis: dynamic_cast incorrectly returns 0 >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: sw-bug >Submitter-Id: net >Arrival-Date: Mon Sep 10 16:06:01 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Philip Hubbard / Florian Kainz, Industrial Light + Magic >Release: unknown-1.0 >Organization: >Environment: gcc 3.0.1 on RedHat Linux 7.1 / Pentium % g++ -v Reading specs from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.0.1/specs Configured with: ../gcc-3.0.1/configure --enable-threads --prefix=/usr/local --enable-languages=c,c++ Thread model: posix gcc version 3.0.1 >Description: dynamic_cast incorrectly returns 0 in programs that load dynamic shared objects (DSOs) via dlopen(). Header file assumes that typeinfo names are merged across all DSOs in a program if weak symbols are supported. At least on Linux, this assumption is wrong for DSOs loaded via dlopen(). >How-To-Repeat: Reproducing the bug requires multiple source files: a.C a.h main.C Makefile The files are listed below. The example program should print: castInMain() 1 castInDso() 1 castInMain() 1 castInDso() 1 The program prints this instead: castInMain() 1 castInDso() 0 castInMain() 0 castInDso() 1 The source files: :::::::::::::: a.C :::::::::::::: #include #include extern "C" { D * DInDso () { static D d; return &d; } bool castInDso (B *b) { std::cout << "castInDso()\n"; return 0 != dynamic_cast (b); } } :::::::::::::: a.h :::::::::::::: struct B { virtual ~B() {} }; struct D: public B { virtual ~D() {} }; :::::::::::::: main.C :::::::::::::: #include #include #include using std::cout; using std::endl; extern "C" { typedef bool func1 (B *); typedef D * func2 (); } bool castInMain (B *b) { std::cout << "castInMain()\n"; return 0 != dynamic_cast (b); } int main () { void *liba = dlopen ("./liba.so", RTLD_LAZY); if (!liba) { cout << dlerror () << endl; return 1; } func1 *castInDso = (func1 *) dlsym (liba, "castInDso"); if (!castInDso) { cout << dlerror () << endl; return 1; } func2 *DInDso = (func2 *) dlsym (liba, "DInDso"); if (!DInDso) { cout << dlerror () << endl; return 1; } { D d; cout << castInMain (&d) << endl; cout << castInDso (&d) << endl; } { D *d = DInDso(); cout << castInMain (d) << endl; cout << castInDso (d) << endl; } } :::::::::::::: Makefile :::::::::::::: t = liba.so test all: $t clean: rm -f $t core liba.so: a.C a.h g++ -I. -shared -o $@ a.C test: main.C a.h g++ -I. -L. main.C -o $@ -ldl >Fix: *** gcc-3.0.1/libstdc++-v3/libsupc++/typeinfo Wed Jul 11 12:37:58 2001 --- /net/rnd/gs/home/kainz/pub/gcc-3.0.1/libstdc++-v3/libsupc++/typeinfo Mon Sep 10 15:23:30 2001 *************** *** 43,54 **** class __class_type_info; } // namespace __cxxabiv1 ! #if !__GXX_WEAK__ ! // If weak symbols are not supported, typeinfo names are not merged. ! #define __GXX_MERGED_TYPEINFO_NAMES 0 #else ! // On platforms that support weak symbols, typeinfo names are merged. ! #define __GXX_MERGED_TYPEINFO_NAMES 1 #endif namespace std --- 43,65 ---- class __class_type_info; } // namespace __cxxabiv1 ! #if 0 ! ! #if !__GXX_WEAK__ ! // If weak symbols are not supported, typeinfo names are not merged. ! #define __GXX_MERGED_TYPEINFO_NAMES 0 ! #else ! // On platforms that support weak symbols, typeinfo names are merged. ! #define __GXX_MERGED_TYPEINFO_NAMES 1 ! #endif ! #else ! ! // Even if weak symbols are supported, typeinfo names are not ! // always merged. On Linux, dynamic shared objects opened with ! // dlopen() have their own, non-shared copies of typeinfo names. ! #define __GXX_MERGED_TYPEINFO_NAMES 0 ! #endif namespace std >Release-Note: >Audit-Trail: >Unformatted: