brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.2 KiB · 4415e24 Raw
560 lines · cpp
1// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t2// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt3// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables -fstrict-vtable-pointers -mconstructor-aliases4// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST1 %s < %t5// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST2 %s < %t6// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST5 %s < %t7// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST8 %s < %t.opt8// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST9 %s < %t.opt9// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST10 %s < %t.opt10// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST11 %s < %t.opt11// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST12 %s < %t.opt12// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST13 %s < %t.opt13// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST14 %s < %t.opt14// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST15 %s < %t.opt15// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST16 %s < %t.opt16// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST17 %s < %t.opt17// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable18 19 20#include <typeinfo>21 22// CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant23// CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant24namespace Test1 {25 26struct A {27  A();28  virtual void f();29  virtual ~A() { }30};31 32A::A() { }33 34void f(A* a) {35  a->f();36};37 38// CHECK-LABEL: define{{.*}} void @_ZN5Test11gEv39// CHECK: call void @_ZN5Test11A1fEv40void g() {41  A a;42  f(&a);43}44 45}46 47// Test2::A's key function (f) is defined in this translation unit, but when48// we're doing codegen for the typeid(A) call, we don't know that yet.49// This tests mainly that the typeinfo and typename constants have their linkage50// updated correctly.51 52// CHECK-TEST2: @_ZTIN5Test21AE ={{.*}} constant53// CHECK-TEST2: @_ZTSN5Test21AE ={{.*}} constant54// CHECK-TEST2: @_ZTVN5Test21AE ={{.*}} unnamed_addr constant55namespace Test2 {56  struct A {57    virtual void f();58  };59 60  const std::type_info &g() {61    return typeid(A);62  };63 64  void A::f() { }65}66 67// Test that we don't assert on this test.68namespace Test3 {69 70struct A {71  virtual void f();72  virtual ~A() { }73};74 75struct B : A {76  B();77  virtual void f();78};79 80B::B() { }81 82void g(A* a) {83  a->f();84};85 86}87 88// PR9114, test that we don't try to instantiate RefPtr<Node>.89namespace Test4 {90 91template <class T> struct RefPtr {92  T* p;93  ~RefPtr() {94    p->deref();95  }96};97 98struct A {99  virtual ~A();100};101 102struct Node;103 104struct B : A {105  virtual void deref();106  RefPtr<Node> m;107};108 109void f() {110  RefPtr<B> b;111}112 113}114 115// PR9130, test that we emit a definition of A::f.116// CHECK-TEST5-LABEL: define linkonce_odr void @_ZN5Test51A1fEv117namespace Test5 {118 119struct A {120  virtual void f() { }121};122 123struct B : A { 124  virtual ~B();125};126 127B::~B() { }128 129}130 131// Check that we don't assert on this test.132namespace Test6 {133 134struct A {135  virtual ~A();136  int a;137};138 139struct B {140  virtual ~B();141  int b;142};143 144struct C : A, B { 145  C();146};147 148struct D : C {149  virtual void f();150  D();151};152 153D::D() { }154 155}156 157namespace Test7 {158 159struct c1 {};160struct c10 : c1{161  virtual void foo ();162};163struct c11 : c10, c1{164  virtual void f6 ();165};166struct c28 : virtual c11{167  void f6 ();168};169}170 171namespace Test8 {172// CHECK-TEST8: @_ZTVN5Test81YE = available_externally unnamed_addr constant173// vtable for X is not generated because there are no stores here174struct X {175  X();176  virtual void foo();177};178struct Y : X {179  void foo();180};181 182void g(X* p) { p->foo(); }183void f() {184  Y y;185  g(&y);186  X x;187  g(&x);188}189 190}  // Test8191 192namespace Test9 {193// All virtual functions are outline, so we can assume that it will194// be generated in translation unit where foo is defined.195// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant196// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant197struct A {198  virtual void foo();199  virtual void bar();200};201void A::bar() {}202 203struct B : A {204  void foo();205};206 207void g() {208  A a;209  a.foo();210  B b;211  b.foo();212}213 214}  // Test9215 216namespace Test10 {217 218// because A's key function is defined here, vtable is generated in this TU219// CHECK-TEST10-DAG: @_ZTVN6Test101AE ={{.*}} unnamed_addr constant220// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE ={{.*}} unnamed_addr constant221struct A {222  virtual void foo();223  virtual void bar();224};225void A::foo() {}226 227// Because key function is inline we will generate vtable as linkonce_odr.228// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant229// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant230struct D : A {231  void bar();232};233inline void D::bar() {}234 235// Because B has outline all virtual functions, we can refer to them.236// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant237struct B : A {238  void foo();239  void bar();240};241 242// C's key function (car) is outline, but C has inline virtual function so we243// can't guarantee that we will be able to refer to bar from name244// so (at the moment) we can't emit vtable available_externally.245// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant246// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant247struct C : A {248  void bar() {}               // defined in body - not key function249  virtual inline void gar();  // inline in body - not key function250  virtual void car();251};252 253// Inline definition outside body, so we can't emit vtable available_externally254// (see previous).255// CHECK-TEST10-DAG: @_ZTVN6Test101FE = external unnamed_addr constant256struct F : A {257  void foo();258  virtual void cat();         // inline outside body259};260inline void F::cat() {}261 262// no key function, vtable will be generated everywhere it will be used263// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant264// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant265 266struct E : A {};267 268void h(A& a) {269  a.foo();270  a.bar();271}272 273void g() {274  A a;275  h(a);276  B b;277  h(b);278  C c;279  h(c);280  D d;281  h(d);282  E e;283  h(e);284  F f;285  h(f);286}287 288}  // Test10289 290namespace Test11 {291struct D;292// Can emit C's vtable available_externally.293// CHECK-TEST11: @_ZTVN6Test111CE = available_externally unnamed_addr constant294struct C {295  virtual D& operator=(const D&);296};297 298// Can emit D's vtable available_externally.299// CHECK-TEST11: @_ZTVN6Test111DE = available_externally unnamed_addr constant300struct D : C {301  virtual void key();302};303D f();304 305void g(D& a) {306  C c;307  c = a;308  a.key();309  a.key();310}311void g() {312  D d;313  d = f();314  g(d);315}316}  // Test 11317 318namespace Test12 {319 320// CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant321// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant322struct A {323  virtual void foo();324  virtual ~A() {}325};326// CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant327// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant328struct B : A {329  void foo();330};331 332void g() {333  A a;334  a.foo();335  B b;336  b.foo();337}338}339 340namespace Test13 {341 342// CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant343// CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant344// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant345// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant346 347struct A {348  virtual ~A();349};350struct B : A {351  virtual void f();352  void operator delete(void *);353  ~B() {}354};355 356void g() {357  A *b = new B;358}359}360 361namespace Test14 {362 363// CHECK-TEST14: @_ZTVN6Test141AE = available_externally unnamed_addr constant364struct A {365  virtual void f();366  void operator delete(void *);367  ~A();368};369 370void g() {371  A *b = new A;372  delete b;373}374}375 376namespace Test15 {377// In this test D's vtable has two slots for function f(), but uses only one,378// so the second slot is set to null.379// CHECK-TEST15: @_ZTVN6Test151DE = available_externally unnamed_addr constant380struct A { virtual void f() {} };381struct B : virtual A {};382struct C : virtual A {};383struct D : B, C {384  virtual void g();385  void f();386};387 388void test() {389  D * d = new D;390  d->f();391}392}393 394namespace Test16 {395// S has virtual method that is hidden, because of it we can't396// generate available_externally vtable for it.397// CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant398// CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally399// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant400// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally401 402struct S {403  __attribute__((visibility("hidden"))) virtual void doStuff();404};405 406struct S2 {407  virtual void doStuff();408  __attribute__((visibility("hidden"))) void unused();409 410};411 412void test() {413  S *s = new S;414  s->doStuff();415 416  S2 *s2 = new S2;417  s2->doStuff();418}419}420 421namespace Test17 {422// This test checks if we emit vtables opportunistically.423// CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally424// CHECK-TEST17-DAG: @_ZTVN6Test171BE = external425// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171AE = available_externally426// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171BE = available_externally427// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD2Ev(428// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD0Ev(429 430struct A {431  virtual void key();432  virtual void bar() {}433};434 435// We won't gonna use deleting destructor for this type, which will disallow436// emitting vtable as available_externally437struct B {438  virtual void key();439  virtual ~B() {}440};441 442void testcaseA() {443  A a;444  a.bar(); // this forces to emit definition of bar445}446 447void testcaseB() {448  B b; // This only forces emitting of complete object destructor449}450 451} // namespace Test17452 453namespace Test18 {454// Here vtable will be only emitted because it is referenced by assume-load455// after the Derived construction.456// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test187DerivedE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN6Test187DerivedE, {{.*}} @_ZN6Test184Base3funEv, {{.*}} @_ZN6Test184BaseD2Ev, {{.*}} @_ZN6Test187DerivedD0Ev457// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test187DerivedD0Ev458// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test184BaseD2Ev459// CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN6Test184Base3funEv460// CHECK-FORCE-EMIT-DAG: @_ZTIN6Test187DerivedE = linkonce_odr constant461 462struct Base {463  virtual int fun() { return 42; }464  virtual ~Base() { }465};466 467struct Derived : Base {468  Derived();469};470 471int foo() {472  Derived *der = new Derived();473  return der->fun();474}475}476 477namespace TestTemplates {478 479// CHECK-FORCE-EMIT-DAG: @_ZTVN13TestTemplates8TemplateIiEE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN13TestTemplates8TemplateIiEE, {{.*}} @_ZN13TestTemplates8TemplateIiE3fooEi, {{.*}}@_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi, {{.*}}@_ZN13TestTemplates8TemplateIiED1Ev, {{.*}}@_ZN13TestTemplates8TemplateIiED0Ev480// CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi481 482template<class T>483struct Template {484  Template();485  virtual T foo(T val);486  // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi487  virtual T thisShouldBeEmittedToo(T val) { return val; }488  virtual ~Template();489};490 491 492struct NonTemplate {493  typedef int T;494  NonTemplate();495  virtual T foo(T val);496  // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates11NonTemplate22thisShouldBeEmittedTooEi497  virtual T thisShouldBeEmittedToo(T val) { return val; }498  virtual ~NonTemplate();499};500 501// CHECK-FORCE-EMIT-DAG: @_ZTVN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiEE = linkonce_odr {{.*}} @_ZTIN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiEE, {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE3fooEi, {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE22thisShouldBeEmittedTooEi, {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiED1Ev, {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiED0Ev502 503struct OuterNonTemplate {504  template<class T>505  struct NestedTemplateInNonTemplate {506    NestedTemplateInNonTemplate();507    virtual T foo(T val);508    // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE22thisShouldBeEmittedTooEi509    virtual T thisShouldBeEmittedToo(T val) { return val; }510    virtual ~NestedTemplateInNonTemplate();511  };512 513  struct NestedNonTemplateInNonTemplate {514    typedef int T;515    NestedNonTemplateInNonTemplate();516    virtual T foo(T val);517    // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates16OuterNonTemplate30NestedNonTemplateInNonTemplate22thisShouldBeEmittedTooEi518    virtual T thisShouldBeEmittedToo(T val) { return val; }519    virtual ~NestedNonTemplateInNonTemplate();520  };521};522 523template<class>524struct OuterTemplate {525  template<class T>526  struct NestedTemplateInTemplate {527    NestedTemplateInTemplate();528    virtual T foo(T val);529    // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates13OuterTemplateIlE24NestedTemplateInTemplateIiE22thisShouldBeEmittedTooEi530    virtual T thisShouldBeEmittedToo(T val) { return val; }531    virtual ~NestedTemplateInTemplate();532  };533 534  struct NestedNonTemplateInTemplate {535    typedef int T;536    NestedNonTemplateInTemplate();537    virtual T foo(T val);538    // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates13OuterTemplateIlE27NestedNonTemplateInTemplate22thisShouldBeEmittedTooEi539    virtual T thisShouldBeEmittedToo(T val) { return val; }540    virtual ~NestedNonTemplateInTemplate();541  };542};543 544template<class T>545int use() {546  T *ptr = new T();547  return ptr->foo(42);548}549 550void test() {551  use<Template<int> >();552  use<OuterTemplate<long>::NestedTemplateInTemplate<int> >();553  use<OuterNonTemplate::NestedTemplateInNonTemplate<int> >();554 555  use<NonTemplate>();556  use<OuterTemplate<long>::NestedNonTemplateInTemplate>();557  use<OuterNonTemplate::NestedNonTemplateInNonTemplate>();558}559}560