Hans Wennborg | c9bd88e | 2014-01-14 19:35:09 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -std=c++11 -fms-extensions -verify -triple i686-pc-win32 %s |
Reid Kleckner | 78af070 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 2 | |
| 3 | // Pointers to free functions |
| 4 | void free_func_default(); |
| 5 | void __cdecl free_func_cdecl(); |
| 6 | void __stdcall free_func_stdcall(); |
| 7 | void __fastcall free_func_fastcall(); |
| 8 | |
| 9 | typedef void ( *fptr_default)(); |
| 10 | typedef void (__cdecl *fptr_cdecl)(); |
| 11 | typedef void (__stdcall *fptr_stdcall)(); |
| 12 | typedef void (__fastcall *fptr_fastcall)(); |
| 13 | |
| 14 | // expected-note@+4 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'fptr_default' (aka 'void (*)()') for 1st argument}} |
| 15 | // expected-note@+3 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'fptr_default' (aka 'void (*)()') for 1st argument}} |
| 16 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void (*)() __attribute__((stdcall))' to 'fptr_default' (aka 'void (*)()') for 1st argument}} |
| 17 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (*)() __attribute__((fastcall))' to 'fptr_default' (aka 'void (*)()') for 1st argument}} |
| 18 | void cb_fptr_default(fptr_default ptr); |
| 19 | // expected-note@+4 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'fptr_cdecl' (aka 'void (*)()') for 1st argument}} |
| 20 | // expected-note@+3 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'fptr_cdecl' (aka 'void (*)()') for 1st argument}} |
| 21 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void (*)() __attribute__((stdcall))' to 'fptr_cdecl' (aka 'void (*)()') for 1st argument}} |
| 22 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (*)() __attribute__((fastcall))' to 'fptr_cdecl' (aka 'void (*)()') for 1st argument}} |
| 23 | void cb_fptr_cdecl(fptr_cdecl ptr); |
| 24 | // expected-note@+3 {{candidate function not viable: no known conversion from 'void ()' to 'fptr_stdcall' (aka 'void (*)() __attribute__((stdcall))') for 1st argument}} |
| 25 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((cdecl))' to 'fptr_stdcall' (aka 'void (*)() __attribute__((stdcall))') for 1st argument}} |
| 26 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'fptr_stdcall' (aka 'void (*)() __attribute__((stdcall))') for 1st argument}} |
| 27 | void cb_fptr_stdcall(fptr_stdcall ptr); |
| 28 | // expected-note@+3 {{candidate function not viable: no known conversion from 'void ()' to 'fptr_fastcall' (aka 'void (*)() __attribute__((fastcall))') for 1st argument}} |
| 29 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((cdecl))' to 'fptr_fastcall' (aka 'void (*)() __attribute__((fastcall))') for 1st argument}} |
| 30 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'fptr_fastcall' (aka 'void (*)() __attribute__((fastcall))') for 1st argument}} |
| 31 | void cb_fptr_fastcall(fptr_fastcall ptr); |
| 32 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'const fptr_default' (aka 'void (*const)()') for 1st argument}} |
| 33 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'const fptr_default' (aka 'void (*const)()') for 1st argument}} |
| 34 | void cb_fptr_const_default(const fptr_default ptr); |
| 35 | |
| 36 | void call_free_func() { |
| 37 | cb_fptr_default(free_func_default); |
| 38 | cb_fptr_default(free_func_cdecl); |
| 39 | cb_fptr_default(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fptr_default'}} |
| 40 | cb_fptr_default(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fptr_default'}} |
| 41 | cb_fptr_default(&free_func_default); |
| 42 | cb_fptr_default(&free_func_cdecl); |
| 43 | cb_fptr_default(&free_func_stdcall); // expected-error {{no matching function for call to 'cb_fptr_default'}} |
| 44 | cb_fptr_default(&free_func_fastcall); // expected-error {{no matching function for call to 'cb_fptr_default'}} |
| 45 | |
| 46 | cb_fptr_cdecl(free_func_default); |
| 47 | cb_fptr_cdecl(free_func_cdecl); |
| 48 | cb_fptr_cdecl(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fptr_cdecl'}} |
| 49 | cb_fptr_cdecl(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fptr_cdecl'}} |
| 50 | cb_fptr_cdecl(&free_func_default); |
| 51 | cb_fptr_cdecl(&free_func_cdecl); |
| 52 | cb_fptr_cdecl(&free_func_stdcall); // expected-error {{no matching function for call to 'cb_fptr_cdecl'}} |
| 53 | cb_fptr_cdecl(&free_func_fastcall); // expected-error {{no matching function for call to 'cb_fptr_cdecl'}} |
| 54 | |
| 55 | cb_fptr_stdcall(free_func_default); // expected-error {{no matching function for call to 'cb_fptr_stdcall'}} |
| 56 | cb_fptr_stdcall(free_func_cdecl); // expected-error {{no matching function for call to 'cb_fptr_stdcall'}} |
| 57 | cb_fptr_stdcall(free_func_stdcall); |
| 58 | cb_fptr_stdcall(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fptr_stdcall'}} |
| 59 | |
| 60 | cb_fptr_fastcall(free_func_default); // expected-error {{no matching function for call to 'cb_fptr_fastcall'}} |
| 61 | cb_fptr_fastcall(free_func_cdecl); // expected-error {{no matching function for call to 'cb_fptr_fastcall'}} |
| 62 | cb_fptr_fastcall(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fptr_fastcall'}} |
| 63 | cb_fptr_fastcall(free_func_fastcall); |
| 64 | |
| 65 | cb_fptr_const_default(free_func_default); |
| 66 | cb_fptr_const_default(free_func_cdecl); |
| 67 | cb_fptr_const_default(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fptr_const_default'}} |
| 68 | cb_fptr_const_default(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fptr_const_default'}} |
| 69 | |
| 70 | } |
| 71 | |
| 72 | // Pointers to variadic functions |
| 73 | // variadic function can't declared stdcall or fastcall |
| 74 | void free_func_variadic_default(int, ...); |
| 75 | void __cdecl free_func_variadic_cdecl(int, ...); |
| 76 | |
| 77 | typedef void ( *fptr_variadic_default)(int, ...); |
| 78 | typedef void (__cdecl *fptr_variadic_cdecl)(int, ...); |
| 79 | |
| 80 | void cb_fptr_variadic_default(fptr_variadic_default ptr); |
| 81 | void cb_fptr_variadic_cdecl(fptr_variadic_cdecl ptr); |
| 82 | |
| 83 | void call_free_variadic_func() { |
| 84 | cb_fptr_variadic_default(free_func_variadic_default); |
| 85 | cb_fptr_variadic_default(free_func_variadic_cdecl); |
| 86 | cb_fptr_variadic_default(&free_func_variadic_default); |
| 87 | cb_fptr_variadic_default(&free_func_variadic_cdecl); |
| 88 | |
| 89 | cb_fptr_variadic_cdecl(free_func_variadic_default); |
| 90 | cb_fptr_variadic_cdecl(free_func_variadic_cdecl); |
| 91 | cb_fptr_variadic_cdecl(&free_func_variadic_default); |
| 92 | cb_fptr_variadic_cdecl(&free_func_variadic_cdecl); |
| 93 | } |
| 94 | |
| 95 | // References to functions |
| 96 | typedef void ( &fref_default)(); |
| 97 | typedef void (__cdecl &fref_cdecl)(); |
| 98 | typedef void (__stdcall &fref_stdcall)(); |
| 99 | typedef void (__fastcall &fref_fastcall)(); |
| 100 | |
| 101 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'fref_default' (aka 'void (&)()') for 1st argument}} |
| 102 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'fref_default' (aka 'void (&)()') for 1st argument}} |
| 103 | void cb_fref_default(fref_default ptr); |
| 104 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'fref_cdecl' (aka 'void (&)()') for 1st argument}} |
| 105 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'fref_cdecl' (aka 'void (&)()') for 1st argument}} |
| 106 | void cb_fref_cdecl(fref_cdecl ptr); |
| 107 | // expected-note@+3 {{candidate function not viable: no known conversion from 'void ()' to 'fref_stdcall' (aka 'void (&)() __attribute__((stdcall))') for 1st argument}} |
| 108 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((cdecl))' to 'fref_stdcall' (aka 'void (&)() __attribute__((stdcall))') for 1st argument}} |
| 109 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'fref_stdcall' (aka 'void (&)() __attribute__((stdcall))') for 1st argument}} |
| 110 | void cb_fref_stdcall(fref_stdcall ptr); |
| 111 | // expected-note@+3 {{candidate function not viable: no known conversion from 'void ()' to 'fref_fastcall' (aka 'void (&)() __attribute__((fastcall))') for 1st argument}} |
| 112 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((cdecl))' to 'fref_fastcall' (aka 'void (&)() __attribute__((fastcall))') for 1st argument}} |
| 113 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'fref_fastcall' (aka 'void (&)() __attribute__((fastcall))') for 1st argument}} |
| 114 | void cb_fref_fastcall(fref_fastcall ptr); |
| 115 | |
| 116 | void call_free_func_ref() { |
| 117 | cb_fref_default(free_func_default); |
| 118 | cb_fref_default(free_func_cdecl); |
| 119 | cb_fref_default(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fref_default'}} |
| 120 | cb_fref_default(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fref_default'}} |
| 121 | |
| 122 | cb_fref_cdecl(free_func_default); |
| 123 | cb_fref_cdecl(free_func_cdecl); |
| 124 | cb_fref_cdecl(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fref_cdecl'}} |
| 125 | cb_fref_cdecl(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fref_cdecl'}} |
| 126 | |
| 127 | cb_fref_stdcall(free_func_default); // expected-error {{no matching function for call to 'cb_fref_stdcall'}} |
| 128 | cb_fref_stdcall(free_func_cdecl); // expected-error {{no matching function for call to 'cb_fref_stdcall'}} |
| 129 | cb_fref_stdcall(free_func_stdcall); |
| 130 | cb_fref_stdcall(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fref_stdcall'}} |
| 131 | |
| 132 | cb_fref_fastcall(free_func_default); // expected-error {{no matching function for call to 'cb_fref_fastcall'}} |
| 133 | cb_fref_fastcall(free_func_cdecl); // expected-error {{no matching function for call to 'cb_fref_fastcall'}} |
| 134 | cb_fref_fastcall(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fref_fastcall'}} |
| 135 | cb_fref_fastcall(free_func_fastcall); |
| 136 | } |
| 137 | |
| 138 | // References to variadic functions |
| 139 | // variadic function can't declared stdcall or fastcall |
| 140 | typedef void ( &fref_variadic_default)(int, ...); |
| 141 | typedef void (__cdecl &fref_variadic_cdecl)(int, ...); |
| 142 | |
| 143 | void cb_fref_variadic_default(fptr_variadic_default ptr); |
| 144 | void cb_fref_variadic_cdecl(fptr_variadic_cdecl ptr); |
| 145 | |
| 146 | void call_free_variadic_func_ref() { |
| 147 | cb_fref_variadic_default(free_func_variadic_default); |
| 148 | cb_fref_variadic_default(free_func_variadic_cdecl); |
| 149 | |
| 150 | cb_fref_variadic_cdecl(free_func_variadic_default); |
| 151 | cb_fref_variadic_cdecl(free_func_variadic_cdecl); |
| 152 | } |
| 153 | |
| 154 | // Pointers to members |
| 155 | namespace NonVariadic { |
| 156 | |
| 157 | struct A { |
| 158 | void member_default(); |
| 159 | void __cdecl member_cdecl(); |
| 160 | void __thiscall member_thiscall(); |
| 161 | }; |
| 162 | |
| 163 | struct B : public A { |
| 164 | }; |
| 165 | |
| 166 | struct C { |
| 167 | void member_default(); |
| 168 | void __cdecl member_cdecl(); |
| 169 | void __thiscall member_thiscall(); |
| 170 | }; |
| 171 | |
| 172 | typedef void ( A::*memb_a_default)(); |
| 173 | typedef void (__cdecl A::*memb_a_cdecl)(); |
| 174 | typedef void (__thiscall A::*memb_a_thiscall)(); |
| 175 | typedef void ( B::*memb_b_default)(); |
| 176 | typedef void (__cdecl B::*memb_b_cdecl)(); |
| 177 | typedef void (__thiscall B::*memb_b_thiscall)(); |
| 178 | typedef void ( C::*memb_c_default)(); |
| 179 | typedef void (__cdecl C::*memb_c_cdecl)(); |
| 180 | typedef void (__thiscall C::*memb_c_thiscall)(); |
| 181 | |
| 182 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_a_default' (aka 'void (NonVariadic::A::*)() __attribute__((thiscall))') for 1st argument}} |
| 183 | void cb_memb_a_default(memb_a_default ptr); |
| 184 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (NonVariadic::A::*)() __attribute__((cdecl))') for 1st argument}} |
| 185 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (NonVariadic::A::*)() __attribute__((cdecl))') for 1st argument}} |
| 186 | void cb_memb_a_cdecl(memb_a_cdecl ptr); |
| 187 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_a_thiscall' (aka 'void (NonVariadic::A::*)() __attribute__((thiscall))') for 1st argument}} |
| 188 | void cb_memb_a_thiscall(memb_a_thiscall ptr); |
| 189 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_b_default' (aka 'void (NonVariadic::B::*)() __attribute__((thiscall))') for 1st argument}} |
| 190 | void cb_memb_b_default(memb_b_default ptr); |
| 191 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (NonVariadic::B::*)() __attribute__((cdecl))') for 1st argument}} |
| 192 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (NonVariadic::B::*)() __attribute__((cdecl))') for 1st argument}} |
| 193 | void cb_memb_b_cdecl(memb_b_cdecl ptr); |
| 194 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_b_thiscall' (aka 'void (NonVariadic::B::*)() __attribute__((thiscall))') for 1st argument}} |
| 195 | void cb_memb_b_thiscall(memb_b_thiscall ptr); |
| 196 | // expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}} |
| 197 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}} |
| 198 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}} |
| 199 | void cb_memb_c_default(memb_c_default ptr); |
| 200 | // expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}} |
| 201 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}} |
| 202 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}} |
| 203 | void cb_memb_c_cdecl(memb_c_cdecl ptr); |
| 204 | // expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}} |
| 205 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}} |
| 206 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}} |
| 207 | void cb_memb_c_thiscall(memb_c_thiscall ptr); |
| 208 | |
| 209 | void call_member() { |
| 210 | cb_memb_a_default(&A::member_default); |
| 211 | cb_memb_a_default(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_a_default'}} |
| 212 | cb_memb_a_default(&A::member_thiscall); |
| 213 | |
| 214 | cb_memb_a_cdecl(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_a_cdecl'}} |
| 215 | cb_memb_a_cdecl(&A::member_cdecl); |
| 216 | cb_memb_a_cdecl(&A::member_thiscall); // expected-error {{no matching function for call to 'cb_memb_a_cdecl'}} |
| 217 | |
| 218 | cb_memb_a_thiscall(&A::member_default); |
| 219 | cb_memb_a_thiscall(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_a_thiscall'}} |
| 220 | cb_memb_a_thiscall(&A::member_thiscall); |
| 221 | } |
| 222 | |
| 223 | void call_member_inheritance() { |
| 224 | cb_memb_b_default(&A::member_default); |
| 225 | cb_memb_b_default(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_b_default'}} |
| 226 | cb_memb_b_default(&A::member_thiscall); |
| 227 | cb_memb_c_default(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_c_default'}} |
| 228 | cb_memb_c_default(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_c_default'}} |
| 229 | cb_memb_c_default(&A::member_thiscall); // expected-error {{no matching function for call to 'cb_memb_c_default'}} |
| 230 | |
| 231 | cb_memb_b_cdecl(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_b_cdecl'}} |
| 232 | cb_memb_b_cdecl(&A::member_cdecl); |
| 233 | cb_memb_b_cdecl(&A::member_thiscall); // expected-error {{no matching function for call to 'cb_memb_b_cdecl'}} |
| 234 | cb_memb_c_cdecl(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_c_cdecl'}} |
| 235 | cb_memb_c_cdecl(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_c_cdecl'}} |
| 236 | cb_memb_c_cdecl(&A::member_thiscall); // expected-error {{no matching function for call to 'cb_memb_c_cdecl'}} |
| 237 | |
| 238 | cb_memb_b_thiscall(&A::member_default); |
| 239 | cb_memb_b_thiscall(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_b_thiscall'}} |
| 240 | cb_memb_b_thiscall(&A::member_thiscall); |
| 241 | cb_memb_c_thiscall(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_c_thiscall'}} |
| 242 | cb_memb_c_thiscall(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_c_thiscall'}} |
| 243 | cb_memb_c_thiscall(&A::member_thiscall); // expected-error {{no matching function for call to 'cb_memb_c_thiscall'}} |
| 244 | } |
| 245 | } // end namespace NonVariadic |
| 246 | |
| 247 | namespace Variadic { |
| 248 | struct A { |
| 249 | void member_default(int, ...); |
| 250 | void __cdecl member_cdecl(int, ...); |
Hans Wennborg | 1e10980 | 2013-10-09 18:10:25 +0000 | [diff] [blame] | 251 | void __thiscall member_thiscall(int, ...); // expected-error {{variadic function cannot use thiscall calling convention}} |
Reid Kleckner | 78af070 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 252 | }; |
| 253 | |
| 254 | struct B : public A { |
| 255 | }; |
| 256 | |
| 257 | struct C { |
| 258 | void member_default(int, ...); |
| 259 | void __cdecl member_cdecl(int, ...); |
| 260 | }; |
| 261 | |
| 262 | typedef void ( A::*memb_a_default)(int, ...); |
| 263 | typedef void (__cdecl A::*memb_a_cdecl)(int, ...); |
| 264 | typedef void ( B::*memb_b_default)(int, ...); |
| 265 | typedef void (__cdecl B::*memb_b_cdecl)(int, ...); |
| 266 | typedef void ( C::*memb_c_default)(int, ...); |
| 267 | typedef void (__cdecl C::*memb_c_cdecl)(int, ...); |
| 268 | |
| 269 | void cb_memb_a_default(memb_a_default ptr); |
| 270 | void cb_memb_a_cdecl(memb_a_cdecl ptr); |
| 271 | void cb_memb_b_default(memb_b_default ptr); |
| 272 | void cb_memb_b_cdecl(memb_b_cdecl ptr); |
| 273 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'memb_c_default' (aka 'void (Variadic::C::*)(int, ...)') for 1st argument}} |
| 274 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_default' (aka 'void (Variadic::C::*)(int, ...)') for 1st argument}} |
| 275 | void cb_memb_c_default(memb_c_default ptr); |
| 276 | // expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'memb_c_cdecl' (aka 'void (Variadic::C::*)(int, ...) __attribute__((cdecl))') for 1st argument}} |
| 277 | // expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (Variadic::C::*)(int, ...) __attribute__((cdecl))') for 1st argument}} |
| 278 | void cb_memb_c_cdecl(memb_c_cdecl ptr); |
| 279 | |
| 280 | void call_member() { |
| 281 | cb_memb_a_default(&A::member_default); |
| 282 | cb_memb_a_default(&A::member_cdecl); |
| 283 | |
| 284 | cb_memb_a_cdecl(&A::member_default); |
| 285 | cb_memb_a_cdecl(&A::member_cdecl); |
| 286 | } |
| 287 | |
| 288 | void call_member_inheritance() { |
| 289 | cb_memb_b_default(&A::member_default); |
| 290 | cb_memb_b_default(&A::member_cdecl); |
| 291 | cb_memb_c_default(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_c_default'}} |
| 292 | cb_memb_c_default(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_c_default'}} |
| 293 | |
| 294 | cb_memb_b_cdecl(&A::member_default); |
| 295 | cb_memb_b_cdecl(&A::member_cdecl); |
| 296 | cb_memb_c_cdecl(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_c_cdecl'}} |
| 297 | cb_memb_c_cdecl(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_c_cdecl'}} |
| 298 | } |
| 299 | } // end namespace Variadic |
| 300 | |
| 301 | namespace MultiChunkDecls { |
| 302 | |
| 303 | // Try to test declarators that have multiple DeclaratorChunks. |
| 304 | struct A { |
| 305 | void __thiscall member_thiscall(int); |
| 306 | }; |
| 307 | |
| 308 | void (A::*return_mptr(short))(int) { |
| 309 | return &A::member_thiscall; |
| 310 | } |
| 311 | |
| 312 | void (A::*(*return_fptr_mptr(char))(short))(int) { |
| 313 | return return_mptr; |
| 314 | } |
| 315 | |
| 316 | typedef void (A::*mptr_t)(int); |
| 317 | mptr_t __stdcall return_mptr_std(short) { |
| 318 | return &A::member_thiscall; |
| 319 | } |
| 320 | |
| 321 | void (A::*(*return_fptr_std_mptr(char))(short))(int) { |
| 322 | return return_mptr_std; // expected-error {{cannot initialize return object of type 'void (MultiChunkDecls::A::*(*)(short))(int) __attribute__((thiscall))' with an lvalue of type 'mptr_t (short) __attribute__((stdcall))'}} |
| 323 | } |
| 324 | |
| 325 | void call_return() { |
| 326 | A o; |
| 327 | void (A::*(*fptr)(short))(int) = return_fptr_mptr('a'); |
| 328 | void (A::*mptr)(int) = fptr(1); |
| 329 | (o.*mptr)(2); |
| 330 | } |
| 331 | |
| 332 | } // end namespace MultiChunkDecls |
| 333 | |
| 334 | namespace MemberPointers { |
| 335 | |
| 336 | struct A { |
| 337 | void __thiscall method_thiscall(); |
| 338 | void __cdecl method_cdecl(); |
| 339 | void __stdcall method_stdcall(); |
| 340 | void __fastcall method_fastcall(); |
| 341 | }; |
| 342 | |
| 343 | void ( A::*mp1)() = &A::method_thiscall; |
| 344 | void (__cdecl A::*mp2)() = &A::method_cdecl; |
| 345 | void (__stdcall A::*mp3)() = &A::method_stdcall; |
| 346 | void (__fastcall A::*mp4)() = &A::method_fastcall; |
| 347 | |
| 348 | // Use a typedef to form the member pointer and verify that cdecl is adjusted. |
| 349 | typedef void ( fun_default)(); |
| 350 | typedef void (__cdecl fun_cdecl)(); |
| 351 | typedef void (__stdcall fun_stdcall)(); |
| 352 | typedef void (__fastcall fun_fastcall)(); |
| 353 | |
Reid Kleckner | 0503a87 | 2013-12-05 01:23:43 +0000 | [diff] [blame] | 354 | fun_default A::*td1 = &A::method_thiscall; |
| 355 | fun_cdecl A::*td2 = &A::method_thiscall; |
Reid Kleckner | 78af070 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 356 | fun_stdcall A::*td3 = &A::method_stdcall; |
| 357 | fun_fastcall A::*td4 = &A::method_fastcall; |
| 358 | |
| 359 | // Round trip the function type through a template, and verify that only cdecl |
| 360 | // gets adjusted. |
Reid Kleckner | 0503a87 | 2013-12-05 01:23:43 +0000 | [diff] [blame] | 361 | template<typename Fn> struct X { typedef Fn A::*p; }; |
Reid Kleckner | 78af070 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 362 | |
Reid Kleckner | 0503a87 | 2013-12-05 01:23:43 +0000 | [diff] [blame] | 363 | X<void ()>::p tmpl1 = &A::method_thiscall; |
| 364 | X<void __cdecl ()>::p tmpl2 = &A::method_thiscall; |
Reid Kleckner | 78af070 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 365 | X<void __stdcall ()>::p tmpl3 = &A::method_stdcall; |
| 366 | X<void __fastcall ()>::p tmpl4 = &A::method_fastcall; |
| 367 | |
Reid Kleckner | 0503a87 | 2013-12-05 01:23:43 +0000 | [diff] [blame] | 368 | X<fun_default >::p tmpl5 = &A::method_thiscall; |
| 369 | X<fun_cdecl >::p tmpl6 = &A::method_thiscall; |
| 370 | X<fun_stdcall >::p tmpl7 = &A::method_stdcall; |
| 371 | X<fun_fastcall>::p tmpl8 = &A::method_fastcall; |
| 372 | |
David Majnemer | a381cda | 2015-11-30 20:34:28 +0000 | [diff] [blame] | 373 | // Make sure we adjust thiscall to cdecl when extracting the function type from |
| 374 | // a member pointer. |
| 375 | template <typename> struct Y; |
| 376 | |
| 377 | template <typename Fn, typename C> |
| 378 | struct Y<Fn C::*> { |
| 379 | typedef Fn *p; |
| 380 | }; |
| 381 | |
| 382 | void __cdecl f_cdecl(); |
| 383 | Y<decltype(&A::method_thiscall)>::p tmpl9 = &f_cdecl; |
| 384 | |
| 385 | |
Reid Kleckner | 78af070 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 386 | } // end namespace MemberPointers |
| 387 | |
| 388 | // Test that lambdas that capture nothing convert to cdecl function pointers. |
| 389 | namespace Lambdas { |
| 390 | |
| 391 | void pass_fptr_cdecl (void (__cdecl *fp)()); |
| 392 | void pass_fptr_stdcall (void (__stdcall *fp)()); // expected-note {{candidate function not viable}} |
| 393 | void pass_fptr_fastcall(void (__fastcall *fp)()); // expected-note {{candidate function not viable}} |
| 394 | |
| 395 | void conversion_to_fptr() { |
| 396 | pass_fptr_cdecl ([]() { } ); |
| 397 | pass_fptr_stdcall ([]() { } ); // expected-error {{no matching function for call}} |
| 398 | pass_fptr_fastcall([]() { } ); // expected-error {{no matching function for call}} |
| 399 | } |
| 400 | |
| 401 | } |