1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s |
2 | |
3 | template<typename T> T &lvalue(); |
4 | template<typename T> T &&xvalue(); |
5 | template<typename T> T prvalue(); |
6 | |
7 | struct X0 { |
8 | int &f() &; |
9 | float &f() &&; |
10 | |
11 | template<typename T> int &ft(T) &; |
12 | template<typename T> float &ft(T) &&; |
13 | |
14 | typedef int &(*func_int_ref)(); |
15 | typedef float &(*func_float_ref)(); |
16 | |
17 | operator func_int_ref() &; |
18 | operator func_float_ref() &&; |
19 | |
20 | void g(); |
21 | |
22 | void c() const; // expected-note {{'c' declared here}} |
23 | void v() volatile; // expected-note {{'v' declared here}} |
24 | void r() __restrict__; // expected-note {{'r' declared here}} |
25 | void cr() const __restrict__; // expected-note {{'cr' declared here}} |
26 | void cv() const volatile; |
27 | void vr() volatile __restrict__; // expected-note {{'vr' declared here}} |
28 | void cvr() const volatile __restrict__; |
29 | |
30 | void lvalue() &; // expected-note 2 {{'lvalue' declared here}} |
31 | void const_lvalue() const&; |
32 | void rvalue() &&; // expected-note {{'rvalue' declared here}} |
33 | |
34 | int &operator+(const X0&) &; |
35 | float &operator+(const X0&) &&; |
36 | |
37 | template<typename T> int &operator+(const T&) &; |
38 | template<typename T> float &operator+(const T&) &&; |
39 | |
40 | int &h() const&; |
41 | float &h() &&; |
42 | int &h2() const&; |
43 | float &h2() const&&; |
44 | }; |
45 | |
46 | void X0::g() { // expected-note {{'g' declared here}} |
47 | int &ir1 = f(); |
48 | int &ir2 = X0::f(); |
49 | } |
50 | |
51 | void test_ref_qualifier_binding() { |
52 | int &ir1 = lvalue<X0>().f(); |
53 | float &fr1 = xvalue<X0>().f(); |
54 | float &fr2 = prvalue<X0>().f(); |
55 | int &ir2 = lvalue<X0>().ft(1); |
56 | float &fr3 = xvalue<X0>().ft(2); |
57 | float &fr4 = prvalue<X0>().ft(3); |
58 | } |
59 | |
60 | void test_ref_qualifier_binding_with_surrogates() { |
61 | int &ir1 = lvalue<X0>()(); |
62 | float &fr1 = xvalue<X0>()(); |
63 | float &fr2 = prvalue<X0>()(); |
64 | } |
65 | |
66 | void test_ref_qualifier_binding_operators() { |
67 | int &ir1 = lvalue<X0>() + prvalue<X0>(); |
68 | float &fr1 = xvalue<X0>() + prvalue<X0>(); |
69 | float &fr2 = prvalue<X0>() + prvalue<X0>(); |
70 | int &ir2 = lvalue<X0>() + 1; |
71 | float &fr3 = xvalue<X0>() + 2; |
72 | float &fr4 = prvalue<X0>() + 3; |
73 | } |
74 | |
75 | void test_ref_qualifier_overloading() { |
76 | int &ir1 = lvalue<X0>().h(); |
77 | float &fr1 = xvalue<X0>().h(); |
78 | float &fr2 = prvalue<X0>().h(); |
79 | int &ir2 = lvalue<X0>().h2(); |
80 | float &fr3 = xvalue<X0>().h2(); |
81 | float &fr4 = prvalue<X0>().h2(); |
82 | } |
83 | |
84 | void test_diagnostics(const volatile X0 &__restrict__ cvr) { |
85 | cvr.g(); // expected-error {{'this' argument to member function 'g' has type 'const volatile X0', but function is not marked const or volatile}} |
86 | cvr.c(); // expected-error {{not marked volatile}} |
87 | cvr.v(); // expected-error {{not marked const}} |
88 | cvr.r(); // expected-error {{not marked const or volatile}} |
89 | cvr.cr(); // expected-error {{not marked volatile}} |
90 | cvr.cv(); |
91 | cvr.vr(); // expected-error {{not marked const}} |
92 | cvr.cvr(); |
93 | |
94 | lvalue<X0>().lvalue(); |
95 | lvalue<X0>().const_lvalue(); |
96 | lvalue<X0>().rvalue(); // expected-error {{'this' argument to member function 'rvalue' is an lvalue, but function has rvalue ref-qualifier}} |
97 | |
98 | xvalue<X0>().lvalue(); // expected-error {{'this' argument to member function 'lvalue' is an rvalue, but function has non-const lvalue ref-qualifier}} |
99 | xvalue<X0>().const_lvalue(); |
100 | xvalue<X0>().rvalue(); |
101 | |
102 | prvalue<X0>().lvalue(); // expected-error {{'this' argument to member function 'lvalue' is an rvalue, but function has non-const lvalue ref-qualifier}} |
103 | prvalue<X0>().const_lvalue(); |
104 | prvalue<X0>().rvalue(); |
105 | } |
106 | |