150
|
1 // RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
|
|
2
|
|
3 using nullptr_t = decltype(nullptr);
|
|
4
|
|
5 template<typename T>
|
|
6 struct Base {
|
|
7 T inner;
|
|
8 };
|
|
9
|
|
10 int z;
|
|
11
|
|
12 template<typename T>
|
|
13 struct X : Base<T> {
|
|
14 static int z;
|
|
15
|
|
16 template<int U>
|
|
17 struct Inner {
|
|
18 };
|
|
19
|
|
20 bool f(T other) {
|
|
21 // A pair of comparisons; 'inner' is a dependent name so can't be assumed
|
|
22 // to be a template.
|
|
23 return this->inner < other > ::z;
|
|
24 }
|
|
25 };
|
|
26
|
|
27 void use_x(X<int> x) { x.f(0); }
|
|
28
|
|
29 template<typename T>
|
|
30 struct Y {
|
|
31 static int z;
|
|
32
|
|
33 template<int U>
|
|
34 struct Inner : Y { // expected-note {{declared here}}
|
|
35 };
|
|
36
|
|
37 bool f(T other) {
|
|
38 // We can determine that 'inner' does not exist at parse time, so can
|
|
39 // perform typo correction in this case.
|
|
40 return this->inner<other>::z; // expected-error {{no template named 'inner' in 'Y<T>'; did you mean 'Inner'?}}
|
|
41 }
|
|
42 };
|
|
43
|
|
44 struct Q { constexpr operator int() { return 0; } };
|
|
45 void use_y(Y<Q> x) { x.f(Q()); }
|