1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s |
2 | |
3 | namespace bullet2 { |
4 | |
5 | // For non-member candidates, if no operand has a class type, only those |
6 | // non-member functions that have a matching enumeration parameter are |
7 | // candidates. |
8 | |
9 | struct B { template<typename T> B(T); }; |
10 | int operator~(B); |
11 | template<typename T> int operator%(B, T); |
12 | enum class E { e }; |
13 | |
14 | template<typename T> int f(T t) { return ~t; } // expected-error {{invalid argument type}} |
15 | template<typename T, typename U> int f(T t, U u) { return t % u; } // expected-error {{invalid operands to}} |
16 | |
17 | int b1 = ~E::e; // expected-error {{invalid argument type}} |
18 | int b2 = f(E::e); // expected-note {{in instantiation of}} |
19 | int b3 = f(0, E::e); |
20 | int b4 = f(E::e, 0); // expected-note {{in instantiation of}} |
21 | |
22 | } |
23 | |
24 | namespace bullet3 { |
25 | |
26 | // This is specifically testing the bullet: |
27 | // "do not have the same parameter-type-list as any non-template |
28 | // non-member candidate." |
29 | // The rest is sort of hard to test separately. |
30 | |
31 | enum E1 { one }; |
32 | enum E2 { two }; |
33 | |
34 | struct A; |
35 | |
36 | A operator >= (E1, E1); |
37 | A operator >= (E1, const E2); |
38 | |
39 | E1 a; |
40 | E2 b; |
41 | |
42 | extern A test1; |
43 | extern decltype(a >= a) test1; |
44 | extern decltype(a >= b) test1; |
45 | |
46 | template <typename T> A operator <= (E1, T); |
47 | extern bool test2; |
48 | extern decltype(a <= a) test2; |
49 | |
50 | extern A test3; |
51 | extern decltype(a <= b) test3; |
52 | |
53 | } |
54 | |