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 | |