[llvm-bugs] [Bug 24409] New: Linker error on Clang on Windows targeting gcc when exporting individual member functions

via llvm-bugs llvm-bugs at lists.llvm.org
Sun Aug 9 16:58:44 PDT 2015


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: unassignedclangbugs at nondot.org
          Reporter: eldlistmailingz at tropicsoft.com
                CC: dgregor at apple.com, llvm-bugs at 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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150809/0feded73/attachment-0001.html>


More information about the llvm-bugs mailing list