blob: 4044f9e513db03cf08d513a0d1ba8ca026304387 [file] [log] [blame]
Hans Wennborgc9bd88e2014-01-14 19:35:09 +00001// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s
2// RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -verify %s
Anders Carlsson8e0317b2009-12-07 08:29:39 +00003
4namespace PR5557 {
5template <class T> struct A {
Nico Weberc4b8e792015-01-13 00:24:46 +00006 A(); // expected-note{{instantiation}}
Anders Carlsson8e0317b2009-12-07 08:29:39 +00007 virtual int a(T x);
8};
9template<class T> A<T>::A() {}
Douglas Gregor0a0f04d2010-01-06 04:44:19 +000010
Anders Carlsson8e0317b2009-12-07 08:29:39 +000011template<class T> int A<T>::a(T x) {
12 return *x; // expected-error{{requires pointer operand}}
13}
14
Nico Weberc4b8e792015-01-13 00:24:46 +000015void f() {
16 A<int> x; // expected-note{{instantiation}}
Douglas Gregor0a0f04d2010-01-06 04:44:19 +000017}
Anders Carlsson8e0317b2009-12-07 08:29:39 +000018
19template<typename T>
20struct X {
21 virtual void f();
22};
23
24template<>
25void X<int>::f() { }
26}
Douglas Gregor0a0f04d2010-01-06 04:44:19 +000027
Nico Weber8b51ae92015-01-13 03:52:11 +000028// Like PR5557, but with a defined destructor instead of a defined constructor.
29namespace PR5557_dtor {
30template <class T> struct A {
31 A(); // Don't have an implicit constructor.
32 ~A(); // expected-note{{instantiation}}
33 virtual int a(T x);
34};
35template<class T> A<T>::~A() {}
36
37template<class T> int A<T>::a(T x) {
38 return *x; // expected-error{{requires pointer operand}}
39}
40
41void f() {
42 A<int> x; // expected-note{{instantiation}}
43}
44}
45
Douglas Gregor0a0f04d2010-01-06 04:44:19 +000046template<typename T>
47struct Base {
48 virtual ~Base() {
49 int *ptr = 0;
50 T t = ptr; // expected-error{{cannot initialize}}
51 }
52};
53
54template<typename T>
55struct Derived : Base<T> {
John McCallf857e0b2010-03-16 05:36:30 +000056 virtual void foo() { }
Douglas Gregor0a0f04d2010-01-06 04:44:19 +000057};
58
John McCallf857e0b2010-03-16 05:36:30 +000059template struct Derived<int>; // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}}
Douglas Gregor0a0f04d2010-01-06 04:44:19 +000060
Douglas Gregorccecc1b2010-01-06 20:27:16 +000061template<typename T>
62struct HasOutOfLineKey {
Reid Kleckner4e326042014-07-16 00:30:59 +000063 HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
Douglas Gregorccecc1b2010-01-06 20:27:16 +000064 virtual T *f(float *fp);
65};
66
67template<typename T>
68T *HasOutOfLineKey<T>::f(float *fp) {
69 return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
70}
71
Reid Kleckner4e326042014-07-16 00:30:59 +000072HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}}
Douglas Gregor88d292c2010-05-13 16:44:06 +000073
74namespace std {
75 class type_info;
76}
77
78namespace PR7114 {
79 class A { virtual ~A(); }; // expected-note{{declared private here}}
80
81 template<typename T>
82 class B {
83 public:
84 class Inner : public A { }; // expected-error{{base class 'PR7114::A' has private destructor}}
85 static Inner i;
86 static const unsigned value = sizeof(i) == 4;
87 };
88
89 int f() { return B<int>::value; }
90
Hans Wennborg9125b082014-01-13 19:48:13 +000091#ifdef MSABI
92 void test_typeid(B<float>::Inner bfi) { // expected-note{{implicit destructor}}
93 (void)typeid(bfi);
94#else
Douglas Gregor88d292c2010-05-13 16:44:06 +000095 void test_typeid(B<float>::Inner bfi) {
Richard Smithf24e6e72013-06-13 03:34:55 +000096 (void)typeid(bfi); // expected-note{{implicit destructor}}
Hans Wennborg9125b082014-01-13 19:48:13 +000097#endif
Douglas Gregor88d292c2010-05-13 16:44:06 +000098 }
99
100 template<typename T>
101 struct X : A {
102 void f() { }
103 };
104
Hans Wennborg9125b082014-01-13 19:48:13 +0000105 void test_X(X<int> &xi, X<float> &xf) {
Douglas Gregor88d292c2010-05-13 16:44:06 +0000106 xi.f();
107 }
108}
Eli Friedmanf8cab732013-06-20 01:47:05 +0000109
110namespace DynamicCast {
111 struct Y {};
112 template<typename T> struct X : virtual Y {
Nico Weberb3a99782015-01-26 06:23:36 +0000113 virtual void foo() { T x; }
Eli Friedmanf8cab732013-06-20 01:47:05 +0000114 };
115 template<typename T> struct X2 : virtual Y {
116 virtual void foo() { T x; }
117 };
Nico Weberb3a99782015-01-26 06:23:36 +0000118 Y* f(X<void>* x) { return dynamic_cast<Y*>(x); }
Eli Friedmanf8cab732013-06-20 01:47:05 +0000119 Y* f2(X<void>* x) { return dynamic_cast<Y*>(x); }
120}
Reid Kleckner4e326042014-07-16 00:30:59 +0000121
122namespace avoid_using_vtable {
123// We shouldn't emit the vtable for this code, in any ABI. If we emit the
124// vtable, we emit an implicit virtual dtor, which calls ~RefPtr, which requires
125// a complete type for DeclaredOnly.
126//
127// Previously we would reference the vtable in the MS C++ ABI, even though we
128// don't need to emit either the ctor or the dtor. In the Itanium C++ ABI, the
129// 'trace' method is the key function, so even though we use the vtable, we
130// don't emit it.
131
132template <typename T>
133struct RefPtr {
134 T *m_ptr;
135 ~RefPtr() { m_ptr->deref(); }
136};
137struct DeclaredOnly;
138struct Base {
139 virtual ~Base();
140};
141
142struct AvoidVTable : Base {
143 RefPtr<DeclaredOnly> m_insertionStyle;
144 virtual void trace();
145 AvoidVTable();
146};
147// Don't call the dtor, because that will emit an implicit dtor, and require a
148// complete type for DeclaredOnly.
149void foo() { new AvoidVTable; }
150}
151
152namespace vtable_uses_incomplete {
153// Opposite of the previous test that avoids a vtable, this one tests that we
154// use the vtable when the ctor is defined inline.
155template <typename T>
156struct RefPtr {
157 T *m_ptr;
158 ~RefPtr() { m_ptr->deref(); } // expected-error {{member access into incomplete type 'vtable_uses_incomplete::DeclaredOnly'}}
159};
160struct DeclaredOnly; // expected-note {{forward declaration of 'vtable_uses_incomplete::DeclaredOnly'}}
161struct Base {
162 virtual ~Base();
163};
164
165struct UsesVTable : Base {
166 RefPtr<DeclaredOnly> m_insertionStyle;
167 virtual void trace();
168 UsesVTable() {} // expected-note {{in instantiation of member function 'vtable_uses_incomplete::RefPtr<vtable_uses_incomplete::DeclaredOnly>::~RefPtr' requested here}}
169};
170}