virtual-member-functions.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s
  2. // RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -verify %s
  3. namespace PR5557 {
  4. template <class T> struct A {
  5. A(); // expected-note{{instantiation}}
  6. virtual int a(T x);
  7. };
  8. template<class T> A<T>::A() {}
  9. template<class T> int A<T>::a(T x) {
  10. return *x; // expected-error{{requires pointer operand}}
  11. }
  12. void f() {
  13. A<int> x; // expected-note{{instantiation}}
  14. }
  15. template<typename T>
  16. struct X {
  17. virtual void f();
  18. };
  19. template<>
  20. void X<int>::f() { }
  21. }
  22. // Like PR5557, but with a defined destructor instead of a defined constructor.
  23. namespace PR5557_dtor {
  24. template <class T> struct A {
  25. A(); // Don't have an implicit constructor.
  26. ~A(); // expected-note{{instantiation}}
  27. virtual int a(T x);
  28. };
  29. template<class T> A<T>::~A() {}
  30. template<class T> int A<T>::a(T x) {
  31. return *x; // expected-error{{requires pointer operand}}
  32. }
  33. void f() {
  34. A<int> x; // expected-note{{instantiation}}
  35. }
  36. }
  37. template<typename T>
  38. struct Base {
  39. virtual ~Base() {
  40. int *ptr = 0;
  41. T t = ptr; // expected-error{{cannot initialize}}
  42. }
  43. };
  44. template<typename T>
  45. struct Derived : Base<T> {
  46. virtual void foo() { }
  47. };
  48. template struct Derived<int>; // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}}
  49. template<typename T>
  50. struct HasOutOfLineKey {
  51. HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
  52. virtual T *f(float *fp);
  53. };
  54. template<typename T>
  55. T *HasOutOfLineKey<T>::f(float *fp) {
  56. return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
  57. }
  58. HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}}
  59. namespace std {
  60. class type_info;
  61. }
  62. namespace PR7114 {
  63. class A { virtual ~A(); }; // expected-note{{declared private here}}
  64. template<typename T>
  65. class B {
  66. public:
  67. class Inner : public A { }; // expected-error{{base class 'PR7114::A' has private destructor}}
  68. static Inner i;
  69. static const unsigned value = sizeof(i) == 4;
  70. };
  71. int f() { return B<int>::value; }
  72. #ifdef MSABI
  73. void test_typeid(B<float>::Inner bfi) { // expected-note{{implicit destructor}}
  74. (void)typeid(bfi);
  75. #else
  76. void test_typeid(B<float>::Inner bfi) {
  77. (void)typeid(bfi); // expected-note{{implicit destructor}}
  78. #endif
  79. }
  80. template<typename T>
  81. struct X : A {
  82. void f() { }
  83. };
  84. void test_X(X<int> &xi, X<float> &xf) {
  85. xi.f();
  86. }
  87. }
  88. namespace DynamicCast {
  89. struct Y {};
  90. template<typename T> struct X : virtual Y {
  91. virtual void foo() { T x; }
  92. };
  93. template<typename T> struct X2 : virtual Y {
  94. virtual void foo() { T x; }
  95. };
  96. Y* f(X<void>* x) { return dynamic_cast<Y*>(x); }
  97. Y* f2(X<void>* x) { return dynamic_cast<Y*>(x); }
  98. }
  99. namespace avoid_using_vtable {
  100. // We shouldn't emit the vtable for this code, in any ABI. If we emit the
  101. // vtable, we emit an implicit virtual dtor, which calls ~RefPtr, which requires
  102. // a complete type for DeclaredOnly.
  103. //
  104. // Previously we would reference the vtable in the MS C++ ABI, even though we
  105. // don't need to emit either the ctor or the dtor. In the Itanium C++ ABI, the
  106. // 'trace' method is the key function, so even though we use the vtable, we
  107. // don't emit it.
  108. template <typename T>
  109. struct RefPtr {
  110. T *m_ptr;
  111. ~RefPtr() { m_ptr->deref(); }
  112. };
  113. struct DeclaredOnly;
  114. struct Base {
  115. virtual ~Base();
  116. };
  117. struct AvoidVTable : Base {
  118. RefPtr<DeclaredOnly> m_insertionStyle;
  119. virtual void trace();
  120. AvoidVTable();
  121. };
  122. // Don't call the dtor, because that will emit an implicit dtor, and require a
  123. // complete type for DeclaredOnly.
  124. void foo() { new AvoidVTable; }
  125. }
  126. namespace vtable_uses_incomplete {
  127. // Opposite of the previous test that avoids a vtable, this one tests that we
  128. // use the vtable when the ctor is defined inline.
  129. template <typename T>
  130. struct RefPtr {
  131. T *m_ptr;
  132. ~RefPtr() { m_ptr->deref(); } // expected-error {{member access into incomplete type 'vtable_uses_incomplete::DeclaredOnly'}}
  133. };
  134. struct DeclaredOnly; // expected-note {{forward declaration of 'vtable_uses_incomplete::DeclaredOnly'}}
  135. struct Base {
  136. virtual ~Base();
  137. };
  138. struct UsesVTable : Base {
  139. RefPtr<DeclaredOnly> m_insertionStyle;
  140. virtual void trace();
  141. UsesVTable() {} // expected-note {{in instantiation of member function 'vtable_uses_incomplete::RefPtr<vtable_uses_incomplete::DeclaredOnly>::~RefPtr' requested here}}
  142. };
  143. }