https://llvm.org/bugs/show_bug.cgi?id=24409
Bug ID: 24409 Summary: Linker error on Clang on Windows targeting gcc when exporting individual member functions Product: clang Version: trunk Hardware: PC OS: Windows NT Status: NEW Severity: release blocker Priority: P Component: C++ Assignee: unassignedclangb...@nondot.org Reporter: eldlistmaili...@tropicsoft.com CC: dgre...@apple.com, llvm-bugs@lists.llvm.org Classification: Unclassified When exporting individual member functions of a class clang does not export the RTTI of that class, leading to a linker error when the class itself is the type of an exception thrown from outside the DLL in which the class is defined. // ex_decl.hpp #ifndef EX_DECL_HPP #define EX_DECL_HPP #if defined(BLD_EX_EXAMPLE) #define EX_DECL __attribute__((__dllexport__)) #else #define EX_DECL __attribute__((__dllimport__)) #endif #define EX_VISIBLE __attribute__((__visibility__("default"))) #endif // EX_DECL_HPP // ex_exception.hpp #ifndef EX_EXCEPTION_HPP #define EX_EXCEPTION_HPP #include <exception> #include "ex_decl.hpp" class EX_VISIBLE ex_exception : public virtual std::exception { private: char m_buffer[128]; protected: EX_DECL unsigned int append(unsigned int l, const char * a); EX_DECL ex_exception() ; public: typedef enum { no_exception, other_exception } ex_exception_code; ex_exception_code code; EX_DECL ex_exception(ex_exception_code c,const char * e1 = 0,const char * e2 = 0) ; EX_DECL ex_exception(ex_exception const &) ; virtual EX_DECL ~ex_exception() throw() ; virtual EX_DECL const char * what() const throw() ; }; #endif // EX_EXCEPTION_HPP // ex_exception.cpp #include <exception> #include <cstring> #define BLD_EX_EXAMPLE #include "ex_exception.hpp" EX_DECL unsigned int ex_exception::append(unsigned int l, const char * a){ while(l < (sizeof(m_buffer) - 1)){ char c = *a++; if('\0' == c) break; m_buffer[l++] = c; } m_buffer[l] = '\0'; return l; } EX_DECL ex_exception::ex_exception(ex_exception_code c,const char * e1,const char * e2) : code(c) { unsigned int length = 0; switch(code){ case no_exception: length = append(length, "uninitialized exception"); break; case other_exception: length = append(length, "unknown derived exception"); break; default: length = append(length, "programming error"); break; } } EX_DECL ex_exception::ex_exception(ex_exception const & oth) : std::exception(oth),code(oth.code) { std::memcpy(m_buffer,oth.m_buffer,sizeof m_buffer); } EX_DECL ex_exception::~ex_exception() throw() {} EX_DECL const char * ex_exception::what() const throw() { return m_buffer; } EX_DECL ex_exception::ex_exception() : code(no_exception) {} // Compile ex_exception.cpp clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -Wno-unused-local-typedef -Wno-dll-attribute-on-redeclaration -O0 -g -fno-inline -Wall -g -march=i686 -m32 -o "ex_exception.obj" "ex_exception.cpp" // ex_xml_exception.hpp #ifndef EX_XML_EXCEPTION_HPP #define EX_XML_EXCEPTION_HPP #include <exception> #include "ex_decl.hpp" #include "ex_exception.hpp" class EX_VISIBLE ex_xml_exception : public virtual ex_exception { public: typedef enum { xml_archive_parsing_error, xml_archive_tag_mismatch, xml_archive_tag_name_error } ex_exception_code; EX_DECL ex_xml_exception(ex_exception_code c,const char * e1 = 0,const char * e2 = 0); EX_DECL ex_xml_exception(ex_xml_exception const &) ; virtual EX_DECL ~ex_xml_exception() throw() ; }; #endif // EX_XML_EXCEPTION_HPP // ex_xml_exception.cpp #include <exception> #define BLD_EX_EXAMPLE #include "ex_xml_exception.hpp" EX_DECL ex_xml_exception::ex_xml_exception(ex_exception_code c,const char * e1,const char * e2) : ex_exception(other_exception, e1, e2) { switch(c){ case xml_archive_parsing_error: ex_exception::append(0, "unrecognized XML syntax"); break; case xml_archive_tag_mismatch: ex_exception::append(0, "XML start/end tag mismatch"); if(0 != e1){ ex_exception::append(0, " - "); ex_exception::append(0, e1); } break; case xml_archive_tag_name_error: ex_exception::append(0, "Invalid XML tag name"); break; default: ex_exception::append(0, "programming error"); break; } } EX_DECL ex_xml_exception::ex_xml_exception(ex_xml_exception const & oth) : std::exception(oth),ex_exception(oth){} EX_DECL ex_xml_exception::~ex_xml_exception() throw() {} // Compile ex_xml_exception.cpp clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -Wno-unused-local-typedef -Wno-dll-attribute-on-redeclaration -O0 -g -fno-inline -Wall -g -march=i686 -m32 -o "ex_xml_exception.obj" "ex_xml_exception.cpp" // Link exmp.dll clang++.exe -o "exmp.dll" -Wl,-soname -Wl,exmp.dll -shared -Wl,--start-group "ex_exception.obj" "ex_xml_exception.obj" -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32 // throw_exception_ex.cpp #include "ex_xml_exception.hpp" template<class E> void throw_exception(E const & e) { throw e; } int main(int argc,char * argv[]) { if (argc > 1) { throw_exception(ex_xml_exception(ex_xml_exception::xml_archive_parsing_error)); } return 0; } // Compile throw_exception_ex.cpp clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -Wno-unused-local-typedef -Wno-dll-attribute-on-redeclaration -O0 -g -fno-inline -Wall -g -march=i686 -m32 -o "throw_exception_ex.obj" "throw_exception_ex.cpp" // Link thr_exmp.exe clang++.exe -Wl,-R -Wl,"." -Wl,-rpath-link -Wl,"." -o "thr_exmp.exe" -Wl,--start-group "throw_exception_ex.obj" "exmp.dll" -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32 // Error message from this link throw_exception_ex.obj: In function 'Z15throw_exceptionI16ex_xml_exceptionEvRKT_': throw_exception_ex.cpp:2: undefined reference to `typeinfo for ex_xml_exception' clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation) This is with the latest clang from trunk (r244427) using mingw-64/gcc-5.1 32 bit RTL (i686-5.1.0-posix-dwarf-rt_v4-rev0). Compiling/linking the same code above with mingw-64/gcc-5.1: // Compile ex_exception.cpp g++ -ftemplate-depth-128 -Wno-unused-local-typedefs -ftrack-macro-expansion=0 -O0 -fno-inline -Wall -g -march=i686 -m32 -fvisibility-inlines-hidden -fvisibility=hidden -c -o "ex_exception.o" "ex_exception.cpp" // Compile ex_xml_exception.cpp g++ -ftemplate-depth-128 -Wno-unused-local-typedefs -ftrack-macro-expansion=0 -O0 -fno-inline -Wall -g -march=i686 -m32 -fvisibility-inlines-hidden -fvisibility=hidden -c -o "ex_xml_exception.o" "ex_xml_exception.cpp" // Link exmp.dll g++ "-Wl,--out-implib,exmp.dll.a" -o "exmp.dll" -shared -Wl,--start-group "ex_exception.o" "ex_xml_exception.o" -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32 // Compiling throw_exception_ex.cpp g++ -ftemplate-depth-128 -Wno-unused-local-typedefs -ftrack-macro-expansion=0 -O0 -fno-inline -Wall -g -march=i686 -m32 -fvisibility-inlines-hidden -fvisibility=hidden -c -o "throw_exception_ex.o" "throw_exception_ex.cpp" // Link thr_exmp.exe g++ -Wl,-R -Wl,"." -Wl,-rpath-link -Wl,"." -o "thr_exmp.exe" -Wl,--start-group "throw_exception_ex.o" "exmp.dll.a" -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32 produces no errors on the final link. -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs