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



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to