blob: a23bf4e3ee5ef766b14eb52c4f133961abcacd2a [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 {
6 A();
Douglas Gregor88d292c2010-05-13 16:44:06 +00007 virtual void anchor();
Anders Carlsson8e0317b2009-12-07 08:29:39 +00008 virtual int a(T x);
9};
10template<class T> A<T>::A() {}
Douglas Gregor0a0f04d2010-01-06 04:44:19 +000011template<class T> void A<T>::anchor() { }
12
Anders Carlsson8e0317b2009-12-07 08:29:39 +000013template<class T> int A<T>::a(T x) {
14 return *x; // expected-error{{requires pointer operand}}
15}
16
Douglas Gregor0a0f04d2010-01-06 04:44:19 +000017void f(A<int> x) {
Douglas Gregor88d292c2010-05-13 16:44:06 +000018 x.anchor(); // expected-note{{instantiation}}
Douglas Gregor0a0f04d2010-01-06 04:44:19 +000019}
Anders Carlsson8e0317b2009-12-07 08:29:39 +000020
21template<typename T>
22struct X {
23 virtual void f();
24};
25
26template<>
27void X<int>::f() { }
28}
Douglas Gregor0a0f04d2010-01-06 04:44:19 +000029
30template<typename T>
31struct Base {
32 virtual ~Base() {
33 int *ptr = 0;
34 T t = ptr; // expected-error{{cannot initialize}}
35 }
36};
37
38template<typename T>
39struct Derived : Base<T> {
John McCallf857e0b2010-03-16 05:36:30 +000040 virtual void foo() { }
Douglas Gregor0a0f04d2010-01-06 04:44:19 +000041};
42
John McCallf857e0b2010-03-16 05:36:30 +000043template struct Derived<int>; // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}}
Douglas Gregor0a0f04d2010-01-06 04:44:19 +000044
Douglas Gregorccecc1b2010-01-06 20:27:16 +000045template<typename T>
46struct HasOutOfLineKey {
Reid Kleckner4e326042014-07-16 00:30:59 +000047 HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
Douglas Gregorccecc1b2010-01-06 20:27:16 +000048 virtual T *f(float *fp);
49};
50
51template<typename T>
52T *HasOutOfLineKey<T>::f(float *fp) {
53 return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
54}
55
Reid Kleckner4e326042014-07-16 00:30:59 +000056HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}}
Douglas Gregor88d292c2010-05-13 16:44:06 +000057
58namespace std {
59 class type_info;
60}
61
62namespace PR7114 {
63 class A { virtual ~A(); }; // expected-note{{declared private here}}
64
65 template<typename T>
66 class B {
67 public:
68 class Inner : public A { }; // expected-error{{base class 'PR7114::A' has private destructor}}
69 static Inner i;
70 static const unsigned value = sizeof(i) == 4;
71 };
72
73 int f() { return B<int>::value; }
74
Hans Wennborg9125b082014-01-13 19:48:13 +000075#ifdef MSABI
76 void test_typeid(B<float>::Inner bfi) { // expected-note{{implicit destructor}}
77 (void)typeid(bfi);
78#else
Douglas Gregor88d292c2010-05-13 16:44:06 +000079 void test_typeid(B<float>::Inner bfi) {
Richard Smithf24e6e72013-06-13 03:34:55 +000080 (void)typeid(bfi); // expected-note{{implicit destructor}}
Hans Wennborg9125b082014-01-13 19:48:13 +000081#endif
Douglas Gregor88d292c2010-05-13 16:44:06 +000082 }
83
84 template<typename T>
85 struct X : A {
86 void f() { }
87 };
88
Hans Wennborg9125b082014-01-13 19:48:13 +000089 void test_X(X<int> &xi, X<float> &xf) {
Douglas Gregor88d292c2010-05-13 16:44:06 +000090 xi.f();
91 }
92}
Eli Friedmanf8cab732013-06-20 01:47:05 +000093
94namespace DynamicCast {
95 struct Y {};
96 template<typename T> struct X : virtual Y {
97 virtual void foo() { T x; } // expected-error {{variable has incomplete type 'void'}}
98 };
99 template<typename T> struct X2 : virtual Y {
100 virtual void foo() { T x; }
101 };
102 Y* f(X<void>* x) { return dynamic_cast<Y*>(x); } // expected-note {{in instantiation of member function 'DynamicCast::X<void>::foo' requested here}}
103 Y* f2(X<void>* x) { return dynamic_cast<Y*>(x); }
104}
Reid Kleckner4e326042014-07-16 00:30:59 +0000105
106namespace avoid_using_vtable {
107// We shouldn't emit the vtable for this code, in any ABI. If we emit the
108// vtable, we emit an implicit virtual dtor, which calls ~RefPtr, which requires
109// a complete type for DeclaredOnly.
110//
111// Previously we would reference the vtable in the MS C++ ABI, even though we
112// don't need to emit either the ctor or the dtor. In the Itanium C++ ABI, the
113// 'trace' method is the key function, so even though we use the vtable, we
114// don't emit it.
115
116template <typename T>
117struct RefPtr {
118 T *m_ptr;
119 ~RefPtr() { m_ptr->deref(); }
120};
121struct DeclaredOnly;
122struct Base {
123 virtual ~Base();
124};
125
126struct AvoidVTable : Base {
127 RefPtr<DeclaredOnly> m_insertionStyle;
128 virtual void trace();
129 AvoidVTable();
130};
131// Don't call the dtor, because that will emit an implicit dtor, and require a
132// complete type for DeclaredOnly.
133void foo() { new AvoidVTable; }
134}
135
136namespace vtable_uses_incomplete {
137// Opposite of the previous test that avoids a vtable, this one tests that we
138// use the vtable when the ctor is defined inline.
139template <typename T>
140struct RefPtr {
141 T *m_ptr;
142 ~RefPtr() { m_ptr->deref(); } // expected-error {{member access into incomplete type 'vtable_uses_incomplete::DeclaredOnly'}}
143};
144struct DeclaredOnly; // expected-note {{forward declaration of 'vtable_uses_incomplete::DeclaredOnly'}}
145struct Base {
146 virtual ~Base();
147};
148
149struct UsesVTable : Base {
150 RefPtr<DeclaredOnly> m_insertionStyle;
151 virtual void trace();
152 UsesVTable() {} // expected-note {{in instantiation of member function 'vtable_uses_incomplete::RefPtr<vtable_uses_incomplete::DeclaredOnly>::~RefPtr' requested here}}
153};
154}