| 1 | // RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion %s |
| 2 | |
| 3 | typedef __typeof__(((int*)0)-((int*)0)) ptrdiff_t; |
| 4 | |
| 5 | namespace DontResolveTooEarly_WaitForOverloadResolution |
| 6 | { |
| 7 | template <class T> T* f(int); // #1 |
| 8 | template <class T, class U> T& f(U); // #2 |
| 9 | |
| 10 | void g() { |
| 11 | int *ip = f<int>(1); // calls #1 |
| 12 | } |
| 13 | |
| 14 | template <class T> |
| 15 | T* f2(int); |
| 16 | template <class T, class U> |
| 17 | T& f2(U); |
| 18 | |
| 19 | void g2() { |
| 20 | int*ip = (f2<int>)(1); // ok |
| 21 | } |
| 22 | |
| 23 | } // End namespace |
| 24 | |
| 25 | namespace DontAllowUnresolvedOverloadedExpressionInAnUnusedExpression |
| 26 | { |
| 27 | void one() { } |
| 28 | template<class T> void oneT() { } |
| 29 | |
| 30 | void two() { } // expected-note 2 {{possible target for call}} |
| 31 | void two(int) { } // expected-note 2 {{possible target for call}} |
| 32 | template<class T> void twoT() { } // expected-note 2 {{possible target for call}} |
| 33 | template<class T> void twoT(T) { } // expected-note 2 {{possible target for call}} |
| 34 | |
| 35 | void check() |
| 36 | { |
| 37 | one; // expected-warning {{expression result unused}} |
| 38 | two; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} |
| 39 | oneT<int>; // expected-warning {{expression result unused}} |
| 40 | twoT<int>; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} |
| 41 | } |
| 42 | |
| 43 | // check the template function case |
| 44 | template<class T> void check() |
| 45 | { |
| 46 | one; // expected-warning {{expression result unused}} |
| 47 | two; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} |
| 48 | oneT<int>; // expected-warning {{expression result unused}} |
| 49 | twoT<int>; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} |
| 50 | |
| 51 | } |
| 52 | |
| 53 | } |
| 54 | |
| 55 | template<typename T> |
| 56 | void twoT() { } |
| 57 | template<typename T, typename U> |
| 58 | void twoT(T) { } |
| 59 | |
| 60 | |
| 61 | void two() { }; //expected-note 5{{candidate}} |
| 62 | void two(int) { }; //expected-note 5{{candidate}} |
| 63 | |
| 64 | |
| 65 | |
| 66 | void one() { } |
| 67 | template<class T> |
| 68 | void oneT() { } |
| 69 | |
| 70 | template<class T> |
| 71 | void cant_resolve() { } //expected-note 3{{candidate}} |
| 72 | |
| 73 | template<class T> void cant_resolve(T) { }//expected-note 3{{candidate}} |
| 74 | |
| 75 | |
| 76 | int main() |
| 77 | { |
| 78 | |
| 79 | { static_cast<void>(one); } |
| 80 | { (void)(one); } |
| 81 | { static_cast<void>(oneT<int>); } |
| 82 | { (void)(oneT<int>); } |
| 83 | |
| 84 | { static_cast<void>(two); } // expected-error {{address of overloaded function 'two' cannot be static_cast to type 'void'}} |
| 85 | { (void)(two); } // expected-error {{address of overloaded function 'two' cannot be cast to type 'void'}} |
| 86 | { static_cast<void>(twoT<int>); } |
| 87 | { (void)(twoT<int>); } |
| 88 | |
| 89 | |
| 90 | { ptrdiff_t x = reinterpret_cast<ptrdiff_t>(oneT<int>); } |
| 91 | { (void) reinterpret_cast<int (*)(char, double)>(oneT<int>); } |
| 92 | { (void) reinterpret_cast<ptrdiff_t>(one); } |
| 93 | { (void) reinterpret_cast<int (*)(char, double)>(one); } |
| 94 | |
| 95 | { ptrdiff_t x = reinterpret_cast<ptrdiff_t>(twoT<int>); } |
| 96 | { (void) reinterpret_cast<int (*)(char, double)>(twoT<int>); } |
| 97 | { (void) reinterpret_cast<void (*)(int)>(two); } //expected-error {{reinterpret_cast}} |
| 98 | { (void) static_cast<void (*)(int)>(two); } //ok |
| 99 | |
| 100 | { (void) reinterpret_cast<int>(two); } //expected-error {{reinterpret_cast}} |
| 101 | { (void) reinterpret_cast<int (*)(char, double)>(two); } //expected-error {{reinterpret_cast}} |
| 102 | |
| 103 | { bool b = (twoT<int>); } |
| 104 | { bool b = (twoT<int, int>); } |
| 105 | |
| 106 | { bool b = &twoT<int>; //&foo<int>; } |
| 107 | b = &(twoT<int>); } |
| 108 | |
| 109 | { ptrdiff_t x = (ptrdiff_t) &twoT<int>; |
| 110 | x = (ptrdiff_t) &twoT<int>; } |
| 111 | |
| 112 | { ptrdiff_t x = (ptrdiff_t) twoT<int>; |
| 113 | x = (ptrdiff_t) twoT<int>; } |
| 114 | |
| 115 | |
| 116 | { ptrdiff_t x = (ptrdiff_t) &twoT<int,int>; |
| 117 | x = (ptrdiff_t) &twoT<int>; } |
| 118 | |
| 119 | { oneT<int>; &oneT<int>; } //expected-warning 2{{expression result unused}} |
| 120 | { static_cast<void>(cant_resolve<int>); } // expected-error {{address of overload}} |
| 121 | { bool b = cant_resolve<int>; } // expected-error {{address of overload}} |
| 122 | { (void) cant_resolve<int>; } // expected-error {{address of overload}} |
| 123 | |
| 124 | } |
| 125 | |
| 126 | namespace member_pointers { |
| 127 | struct S { |
| 128 | template <typename T> bool f(T) { return false; } // expected-note 4 {{possible target for call}} |
| 129 | template <typename T> static bool g(T) { return false; } |
| 130 | |
| 131 | template <typename T> bool h(T) { return false; } // expected-note 3 {{possible target for call}} |
| 132 | template <int N> static bool h(int) { return false; } // expected-note 3 {{possible target for call}} |
| 133 | }; |
| 134 | |
| 135 | void test(S s) { |
| 136 | if (S::f<char>) return; // expected-error {{call to non-static member function without an object argument}} |
| 137 | if (S::f<int>) return; // expected-error {{call to non-static member function without an object argument}} |
| 138 | if (&S::f<char>) return; |
| 139 | if (&S::f<int>) return; |
| 140 | if (s.f<char>) return; // expected-error {{reference to non-static member function must be called}} |
| 141 | if (s.f<int>) return; // expected-error {{reference to non-static member function must be called}} |
| 142 | if (&s.f<char>) return; // expected-error {{cannot create a non-constant pointer to member function}} |
| 143 | if (&s.f<int>) return; // expected-error {{cannot create a non-constant pointer to member function}} |
| 144 | |
| 145 | if (S::g<char>) return; |
| 146 | if (S::g<int>) return; |
| 147 | if (&S::g<char>) return; |
| 148 | if (&S::g<int>) return; |
| 149 | if (s.g<char>) return; |
| 150 | if (s.g<int>) return; |
| 151 | if (&s.g<char>) return; |
| 152 | if (&s.g<int>) return; |
| 153 | |
| 154 | if (S::h<42>) return; |
| 155 | if (S::h<int>) return; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} |
| 156 | if (&S::h<42>) return; |
| 157 | if (&S::h<int>) return; |
| 158 | if (s.h<42>) return; |
| 159 | if (s.h<int>) return; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} |
| 160 | if (&s.h<42>) return; |
| 161 | if (&s.h<int>) return; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} |
| 162 | |
| 163 | { bool b = S::f<char>; } // expected-error {{call to non-static member function without an object argument}} |
| 164 | { bool b = S::f<int>; } // expected-error {{call to non-static member function without an object argument}} |
| 165 | { bool b = &S::f<char>; } |
| 166 | { bool b = &S::f<int>; } |
| 167 | // These next two errors are terrible. |
| 168 | { bool b = s.f<char>; } // expected-error {{reference to non-static member function must be called}} |
| 169 | { bool b = s.f<int>; } // expected-error {{reference to non-static member function must be called}} |
| 170 | { bool b = &s.f<char>; } // expected-error {{cannot create a non-constant pointer to member function}} |
| 171 | { bool b = &s.f<int>; } // expected-error {{cannot create a non-constant pointer to member function}} |
| 172 | |
| 173 | { bool b = S::g<char>; } |
| 174 | { bool b = S::g<int>; } |
| 175 | { bool b = &S::g<char>; } |
| 176 | { bool b = &S::g<int>; } |
| 177 | { bool b = s.g<char>; } |
| 178 | { bool b = s.g<int>; } |
| 179 | { bool b = &s.g<char>; } |
| 180 | { bool b = &s.g<int>; } |
| 181 | |
| 182 | { bool b = S::h<42>; } |
| 183 | { bool b = S::h<int>; } // expected-error {{cannot form member pointer of type 'bool' without '&' and class name}} |
| 184 | { bool b = &S::h<42>; } |
| 185 | { bool b = &S::h<int>; } |
| 186 | { bool b = s.h<42>; } |
| 187 | { bool b = s.h<int>; } // expected-error {{cannot form member pointer of type 'bool' without '&' and class name}} |
| 188 | { bool b = &s.h<42>; } |
| 189 | { bool b = &s.h<int>; } // expected-error {{cannot form member pointer of type 'bool' without '&' and class name}} |
| 190 | } |
| 191 | } |
| 192 | |