Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

clang doesn't generate "complete object constructor" code when the class contains pure virtual method. #14564

Open Quuxplusone opened 11 years ago

Quuxplusone commented 11 years ago
Bugzilla Link PR14557
Status NEW
Importance P normal
Reported by orchidnju (orchidnju-dummy@yahoo.com.cn)
Reported on 2012-12-10 01:08:48 -0800
Last modified on 2012-12-10 19:21:20 -0800
Version 3.1
Hardware Macintosh MacOS X
CC llvm-bugs@lists.llvm.org, orchidnju-dummy@yahoo.com.cn, richard-llvm@metafoo.co.uk
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
[NOTE] Not sure whether it's clang++ bug, but it's behavior is different from
llvm-g++, so I want to get confirmation on whether clang obey standard and the
behavior is as designed. As a plus, is there any document introduce clang's C++
mangling rule?

[Summary] clang doesn't generate "complete object constructor" (the C1 version)
code when the class contains pure virtual method.

[Reproduce Steps]
1. create ABISample.cpp to include below code. class A is common class, class B
contains 1 pure virtual method.
===============================
class A
{
public:
    A();
};

class B
{
public:
    B();
    virtual void Foo() = 0;
};

A::A() {};
B::B() {};
===============================

2. compile the code with clang++/g++:
- clang++ -c ABISample.cpp -o clang.o
- g++ -c ABISample.cpp -o g++.o

3. use nm to check generated symbols:
$ nm clang.o
00000000000000e0 s EH_frame0
0000000000000000 T __ZN1AC1Ev
00000000000000f8 S __ZN1AC1Ev.eh
0000000000000020 T __ZN1AC2Ev
0000000000000120 S __ZN1AC2Ev.eh
0000000000000030 T __ZN1BC2Ev
0000000000000148 S __ZN1BC2Ev.eh
0000000000000068 S __ZTI1B
0000000000000078 S __ZTS1B
0000000000000050 S __ZTV1B
                 U __ZTVN10__cxxabiv117__class_type_infoE
                 U ___cxa_pure_virtual

$ nm g++.o
00000000000000a8 s EH_frame0
000000000000000a T __ZN1AC1Ev
00000000000000f0 S __ZN1AC1Ev.eh
0000000000000000 T __ZN1AC2Ev
00000000000000c0 S __ZN1AC2Ev.eh
000000000000003c T __ZN1BC1Ev
0000000000000150 S __ZN1BC1Ev.eh
0000000000000014 T __ZN1BC2Ev
0000000000000120 S __ZN1BC2Ev.eh
0000000000000090 S __ZTI1B
00000000000000a0 S __ZTS1B
0000000000000070 S __ZTV1B
                 U __ZTVN10__cxxabiv117__class_type_infoE
                 U ___cxa_pure_virtual

4. compare two symbol list, you can find class B's C1 constructor are generated
by g++ but not clang++:
000000000000003c T __ZN1BC1Ev
0000000000000150 S __ZN1BC1Ev.eh

5. If I remove "= 0" from Foo() to change it from pure virtual to virtual
method, clang will generate C1 constructor.
Quuxplusone commented 11 years ago

Right, B::B can never be called as a complete object constructor, so the C1 form is not necessary. Is this causing you problems somehow?

Quuxplusone commented 11 years ago
(In reply to comment #1)
> Right, B::B can never be called as a complete object constructor, so the C1
> form is not necessary. Is this causing you problems somehow?

Right, from my understanding, C1 will be never called. The issue is, I'm
switching compiler from gcc to clang for a big product with long history. It
uses a self-defined .def file to define all symbols needed to be exported from
a library. We can just state "B::B" inside the private .def file, then use a
private tool (called "mangle") to generate C1/C2 version constructors for the
"B::B" into a definication file known by the compiler. Since clang doesn't
provide C1, the link fails with the exported symbol list.

Since the product is cross platform, we need to use "mangle" tool to generate
corresponding definition file on each platform. The compiler we supported
before on OS X is gcc, and "mangle" heavily depends on the behavior of gcc.The
tool we used isn't strong enough to detect whether the class has pure virtual
method. That's why I want to ask help here.

Is is possible to let clang generate C1, like gcc does?
Or is it possible to let "mangle" knows the mangled name of the constructors
that clang generates for one class?
Quuxplusone commented 11 years ago
(In reply to comment #2)
> Is is possible to let clang generate C1, like gcc does?

There's currently no way to do that.

> Or is it possible to let "mangle" knows the mangled name of the constructors
> that clang generates for one class?

If you have the object files, you could search through them for symbols
matching your constructor name. Alternatively, maybe your linker has a
mechanism to only export symbols if they exist?
Quuxplusone commented 11 years ago
(In reply to comment #3)
> (In reply to comment #2)
> > Is is possible to let clang generate C1, like gcc does?
>
> There's currently no way to do that.
>
> > Or is it possible to let "mangle" knows the mangled name of the constructors
> > that clang generates for one class?
>
> If you have the object files, you could search through them for symbols
> matching your constructor name. Alternatively, maybe your linker has a
> mechanism to only export symbols if they exist?

I only have the header files and the private symbol names like "B::B" in hand
when creating the common symbol file. I'm wondering if I can link with some
llvm libraries to just calcualte out the mangeled symbols just from header
files.

Fortunately, the ld on Mac supports wildcards for symbol name. I'll try to see
if I can use "C?" to work around this issue.