1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 template<typename T>
call_f0(T x)3 void call_f0(T x) {
4   x.Base::f0();
5 }
6 
7 struct Base {
8   void f0();
9 };
10 
11 struct X0 : Base {
12   typedef Base CrazyBase;
13 };
14 
test_f0(X0 x0)15 void test_f0(X0 x0) {
16   call_f0(x0);
17 }
18 
19 template<typename TheBase, typename T>
call_f0_through_typedef(T x)20 void call_f0_through_typedef(T x) {
21   typedef TheBase Base2;
22   x.Base2::f0();
23 }
24 
test_f0_through_typedef(X0 x0)25 void test_f0_through_typedef(X0 x0) {
26   call_f0_through_typedef<Base>(x0);
27 }
28 
29 template<typename TheBase, typename T>
call_f0_through_typedef2(T x)30 void call_f0_through_typedef2(T x) {
31   typedef TheBase CrazyBase; // expected-note{{current scope}}
32   x.CrazyBase::f0(); // expected-error{{ambiguous}} \
33                      // expected-error 2{{no member named}}
34 }
35 
36 struct OtherBase { };
37 
38 struct X1 : Base, OtherBase {
39   typedef OtherBase CrazyBase; // expected-note{{object type}}
40 };
41 
test_f0_through_typedef2(X0 x0,X1 x1)42 void test_f0_through_typedef2(X0 x0, X1 x1) {
43   call_f0_through_typedef2<Base>(x0);
44   call_f0_through_typedef2<OtherBase>(x1); // expected-note{{instantiation}}
45   call_f0_through_typedef2<Base>(x1); // expected-note{{instantiation}}
46 }
47 
48 
49 struct X2 {
50   operator int() const;
51 };
52 
53 template<typename T, typename U>
convert(const U & value)54 T convert(const U& value) {
55   return value.operator T(); // expected-error{{operator long}}
56 }
57 
test_convert(X2 x2)58 void test_convert(X2 x2) {
59   convert<int>(x2);
60   convert<long>(x2); // expected-note{{instantiation}}
61 }
62 
63 template<typename T>
destruct(T * ptr)64 void destruct(T* ptr) {
65   ptr->~T();
66   ptr->T::~T();
67 }
68 
69 template<typename T>
destruct_intptr(int * ip)70 void destruct_intptr(int *ip) {
71   ip->~T();
72   ip->T::~T();
73 }
74 
test_destruct(X2 * x2p,int * ip)75 void test_destruct(X2 *x2p, int *ip) {
76   destruct(x2p);
77   destruct(ip);
78   destruct_intptr<int>(ip);
79 }
80 
81 // PR5220
82 class X3 {
83 protected:
84   template <int> float* &f0();
85   template <int> const float* &f0() const;
f1()86   void f1() {
87     (void)static_cast<float*>(f0<0>());
88   }
f1() const89   void f1() const{
90     (void)f0<0>();
91   }
92 };
93 
94 // Fun with template instantiation and conversions
95 struct X4 {
96   int& member();
97   float& member() const;
98 };
99 
100 template<typename T>
101 struct X5 {
fX5102   void f(T* ptr) { int& ir = ptr->member(); }
gX5103   void g(T* ptr) { float& fr = ptr->member(); }
104 };
105 
test_X5(X5<X4> x5,X5<const X4> x5c,X4 * xp,const X4 * cxp)106 void test_X5(X5<X4> x5, X5<const X4> x5c, X4 *xp, const X4 *cxp) {
107   x5.f(xp);
108   x5c.g(cxp);
109 }
110 
111 // In theory we can do overload resolution at template-definition time on this.
112 // We should at least not assert.
113 namespace test4 {
114   struct Base {
footest4::Base115     template <class T> void foo() {}
116   };
117 
118   template <class T> struct Foo : Base {
testtest4::Foo119     void test() {
120       foo<int>();
121     }
122   };
123 }
124 
125 namespace test5 {
126   template<typename T>
127   struct X {
128     using T::value;
129 
getValuetest5::X130     T &getValue() {
131       return &value;
132     }
133   };
134 }
135 
136 // PR8739
137 namespace test6 {
138   struct A {};
139   struct B {};
140   template <class T> class Base;
141   template <class T> class Derived : public Base<T> {
142     A *field;
get(B ** ptr)143     void get(B **ptr) {
144       // It's okay if at some point we figure out how to diagnose this
145       // at instantiation time.
146       *ptr = field;
147     }
148   };
149 }
150