1*67e74705SXin Li // RUN: not %clang_cc1 -std=c++11 %s -fsyntax-only 2>&1 | FileCheck %s
2*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 %s -fsyntax-only -DWARN 2>&1 | FileCheck %s --check-prefix=CHECK-WARN
3*67e74705SXin Li
4*67e74705SXin Li #ifndef WARN
5*67e74705SXin Li
6*67e74705SXin Li // Ensure that the diagnostics we produce for this situation appear in a
7*67e74705SXin Li // deterministic order. This requires ADL to provide lookup results in a
8*67e74705SXin Li // deterministic order.
9*67e74705SXin Li template<typename T, typename> struct Error { typedef typename T::error error; };
10*67e74705SXin Li struct X { template<typename T> friend typename Error<X, T>::error f(X, T); };
11*67e74705SXin Li struct Y { template<typename T> friend typename Error<Y, T>::error f(T, Y); };
12*67e74705SXin Li
g()13*67e74705SXin Li void g() {
14*67e74705SXin Li f(X(), Y());
15*67e74705SXin Li }
16*67e74705SXin Li
17*67e74705SXin Li // We don't really care which order these two diagnostics appear (although the
18*67e74705SXin Li // order below is source order, which seems best). The crucial fact is that
19*67e74705SXin Li // there is one single order that is stable across multiple runs of clang.
20*67e74705SXin Li //
21*67e74705SXin Li // CHECK: no type named 'error' in 'X'
22*67e74705SXin Li // CHECK: no type named 'error' in 'Y'
23*67e74705SXin Li // CHECK: no matching function for call to 'f'
24*67e74705SXin Li
25*67e74705SXin Li
26*67e74705SXin Li struct Oper {
27*67e74705SXin Li template<typename T, typename U = typename Error<Oper, T>::error> operator T();
28*67e74705SXin Li
29*67e74705SXin Li operator int*();
30*67e74705SXin Li operator float*();
31*67e74705SXin Li operator X*();
32*67e74705SXin Li operator Y*();
33*67e74705SXin Li
34*67e74705SXin Li operator int(*[1])();
35*67e74705SXin Li operator int(*[2])();
36*67e74705SXin Li operator int(*[3])();
37*67e74705SXin Li operator int(*[4])();
38*67e74705SXin Li operator int(*[5])();
39*67e74705SXin Li operator int(*[6])();
40*67e74705SXin Li operator int(*[7])();
41*67e74705SXin Li operator int(*[8])();
42*67e74705SXin Li operator float(*[1])();
43*67e74705SXin Li operator float(*[2])();
44*67e74705SXin Li operator float(*[3])();
45*67e74705SXin Li operator float(*[4])();
46*67e74705SXin Li operator float(*[5])();
47*67e74705SXin Li operator float(*[6])();
48*67e74705SXin Li operator float(*[7])();
49*67e74705SXin Li operator float(*[8])();
50*67e74705SXin Li };
51*67e74705SXin Li int *p = Oper() + 0;
52*67e74705SXin Li
53*67e74705SXin Li // CHECK: no type named 'error' in 'Oper'
54*67e74705SXin Li // CHECK: in instantiation of template class 'Error<Oper, int *>'
55*67e74705SXin Li // CHECK: no type named 'error' in 'Oper'
56*67e74705SXin Li // CHECK: in instantiation of template class 'Error<Oper, float *>'
57*67e74705SXin Li // CHECK: no type named 'error' in 'Oper'
58*67e74705SXin Li // CHECK: in instantiation of template class 'Error<Oper, X *>'
59*67e74705SXin Li // CHECK: no type named 'error' in 'Oper'
60*67e74705SXin Li // CHECK: in instantiation of template class 'Error<Oper, Y *>'
61*67e74705SXin Li
62*67e74705SXin Li #endif
63*67e74705SXin Li
64*67e74705SXin Li template<typename T> struct UndefButUsed {
65*67e74705SXin Li static inline int f();
gUndefButUsed66*67e74705SXin Li static int g() { return f(); }
67*67e74705SXin Li };
68*67e74705SXin Li int undef_but_used = UndefButUsed<int>::g() + UndefButUsed<float>::g() + UndefButUsed<char>::g() + UndefButUsed<void>::g();
69*67e74705SXin Li
70*67e74705SXin Li // CHECK-WARN: inline function 'UndefButUsed<int>::f' is not defined
71*67e74705SXin Li // CHECK-WARN: inline function 'UndefButUsed<float>::f' is not defined
72*67e74705SXin Li // CHECK-WARN: inline function 'UndefButUsed<char>::f' is not defined
73*67e74705SXin Li // CHECK-WARN: inline function 'UndefButUsed<void>::f' is not defined
74