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