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