[PATCH] D47108: Add -fforce-emit-vtables
Krzysztof Pszeniczny via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon May 21 05:12:30 PDT 2018
amharc requested changes to this revision.
amharc added a comment.
This revision now requires changes to proceed.
This is not sound: sometimes the forcefully emitted vtable is incorrect due to destructor aliasing. This happens e.g. in the Bullet benchmark from the llvm test suite. A simplified example follows.
For a translation unit:
struct Base {
virtual int foo() { return 42; }
virtual ~Base() { }
};
struct Derived : Base {
Derived();
};
int foo() {
Derived *der = new Derived();
return der->foo();
}
it emits:
; Function Attrs: nounwind
declare dso_local void @_ZN7DerivedD1Ev(%struct.Derived*) unnamed_addr #6
; Function Attrs: nounwind
declare dso_local void @_ZN7DerivedD0Ev(%struct.Derived*) unnamed_addr #6
@_ZTV7Derived = linkonce_odr dso_local unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI7Derived to i8*), i8* bitcast (i32 (%struct.Base*)* @_ZN4Base3fooEv to i8*), i8* bitcast (void (%struct.Derived*)* @_ZN7DerivedD1Ev to i8*), i8* bitcast (void (%struct.Derived*)* @_ZN7DerivedD0Ev to i8*)] }, comdat, align 8
whereas for TU:
struct Base {
virtual int foo() { return 42; }
virtual ~Base() { }
};
struct Derived : Base {
Derived();
};
Derived::Derived() { }
which emits the whole vtable (even without this patch):
@_ZTV7Derived = linkonce_odr dso_local unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI7Derived to i8*), i8* bitcast (i32 (%struct.Base*)* @_ZN4Base3fooEv to i8*), i8* bitcast (void (%struct.Base*)* @_ZN4BaseD2Ev to i8*), i8* bitcast (void (%struct.Derived*)* @_ZN7DerivedD0Ev to i8*)] }, comdat, align 8
Please note that the complete object destructor `@_ZN7DerivedD1Ev` has been RAUWed with the base object destructor `@_ZN4BaseD2Ev`.
Since this triggers the RAUW case (as opposed to the Alias case) in `ItaniumCXXABI::emitCXXStructor`, the complete object destructor is **not** emitted at all.
Because `Derived` lacks a key function, the vtable is `linkonce_odr` and any of those definitions can be picked. Hence, this code can stop linking at the whim of the linker. :(
Repository:
rL LLVM
https://reviews.llvm.org/D47108
More information about the cfe-commits
mailing list