1 // REQUIRES: x86-registered-target 2 // REQUIRES: nvptx-registered-target 3 4 // Make sure we handle target overloads correctly. 5 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ 6 // RUN: -fsyntax-only -fcuda-target-overloads -verify %s 7 // RUN: %clang_cc1 -triple nvptx64-nvidia-cuda \ 8 // RUN: -fsyntax-only -fcuda-target-overloads -fcuda-is-device -verify %s 9 10 // Check target overloads handling with disabled call target checks. 11 // RUN: %clang_cc1 -DNOCHECKS -triple x86_64-unknown-linux-gnu -fsyntax-only \ 12 // RUN: -fcuda-disable-target-call-checks -fcuda-target-overloads -verify %s 13 // RUN: %clang_cc1 -DNOCHECKS -triple nvptx64-nvidia-cuda -fsyntax-only \ 14 // RUN: -fcuda-disable-target-call-checks -fcuda-target-overloads \ 15 // RUN: -fcuda-is-device -verify %s 16 17 #include "Inputs/cuda.h" 18 19 typedef int (*fp_t)(void); 20 typedef void (*gp_t)(void); 21 22 // Host and unattributed functions can't be overloaded 23 __host__ int hh(void) { return 1; } // expected-note {{previous definition is here}} 24 int hh(void) { return 1; } // expected-error {{redefinition of 'hh'}} 25 26 // H/D overloading is OK 27 __host__ int dh(void) { return 2; } 28 __device__ int dh(void) { return 2; } 29 30 // H/HD and D/HD are not allowed 31 __host__ __device__ int hdh(void) { return 5; } // expected-note {{previous definition is here}} 32 __host__ int hdh(void) { return 4; } // expected-error {{redefinition of 'hdh'}} 33 34 __host__ int hhd(void) { return 4; } // expected-note {{previous definition is here}} 35 __host__ __device__ int hhd(void) { return 5; } // expected-error {{redefinition of 'hhd'}} 36 // expected-warning@-1 {{attribute declaration must precede definition}} 37 // expected-note@-3 {{previous definition is here}} 38 39 __host__ __device__ int hdd(void) { return 7; } // expected-note {{previous definition is here}} 40 __device__ int hdd(void) { return 6; } // expected-error {{redefinition of 'hdd'}} 41 42 __device__ int dhd(void) { return 6; } // expected-note {{previous definition is here}} 43 __host__ __device__ int dhd(void) { return 7; } // expected-error {{redefinition of 'dhd'}} 44 // expected-warning@-1 {{attribute declaration must precede definition}} 45 // expected-note@-3 {{previous definition is here}} 46 47 // Same tests for extern "C" functions 48 extern "C" __host__ int chh(void) {return 11;} // expected-note {{previous definition is here}} 49 extern "C" int chh(void) {return 11;} // expected-error {{redefinition of 'chh'}} 50 51 // H/D overloading is OK 52 extern "C" __device__ int cdh(void) {return 10;} 53 extern "C" __host__ int cdh(void) {return 11;} 54 55 // H/HD and D/HD overloading is not allowed. 56 extern "C" __host__ __device__ int chhd1(void) {return 12;} // expected-note {{previous definition is here}} 57 extern "C" __host__ int chhd1(void) {return 13;} // expected-error {{redefinition of 'chhd1'}} 58 59 extern "C" __host__ int chhd2(void) {return 13;} // expected-note {{previous definition is here}} 60 extern "C" __host__ __device__ int chhd2(void) {return 12;} // expected-error {{redefinition of 'chhd2'}} 61 // expected-warning@-1 {{attribute declaration must precede definition}} 62 // expected-note@-3 {{previous definition is here}} 63 64 // Helper functions to verify calling restrictions. 65 __device__ int d(void) { return 8; } 66 __host__ int h(void) { return 9; } 67 __global__ void g(void) {} 68 extern "C" __device__ int cd(void) {return 10;} 69 extern "C" __host__ int ch(void) {return 11;} 70 71 __host__ void hostf(void) { 72 fp_t dp = d; 73 fp_t cdp = cd; 74 #if !defined(NOCHECKS) 75 // expected-error@-3 {{reference to __device__ function 'd' in __host__ function}} 76 // expected-note@65 {{'d' declared here}} 77 // expected-error@-4 {{reference to __device__ function 'cd' in __host__ function}} 78 // expected-note@68 {{'cd' declared here}} 79 #endif 80 fp_t hp = h; 81 fp_t chp = ch; 82 fp_t dhp = dh; 83 fp_t cdhp = cdh; 84 gp_t gp = g; 85 86 d(); 87 cd(); 88 #if !defined(NOCHECKS) 89 // expected-error@-3 {{no matching function for call to 'd'}} 90 // expected-note@65 {{candidate function not viable: call to __device__ function from __host__ function}} 91 // expected-error@-4 {{no matching function for call to 'cd'}} 92 // expected-note@68 {{candidate function not viable: call to __device__ function from __host__ function}} 93 #endif 94 h(); 95 ch(); 96 dh(); 97 cdh(); 98 g(); // expected-error {{call to global function g not configured}} 99 g<<<0,0>>>(); 100 } 101 102 103 __device__ void devicef(void) { 104 fp_t dp = d; 105 fp_t cdp = cd; 106 fp_t hp = h; 107 fp_t chp = ch; 108 #if !defined(NOCHECKS) 109 // expected-error@-3 {{reference to __host__ function 'h' in __device__ function}} 110 // expected-note@66 {{'h' declared here}} 111 // expected-error@-4 {{reference to __host__ function 'ch' in __device__ function}} 112 // expected-note@69 {{'ch' declared here}} 113 #endif 114 fp_t dhp = dh; 115 fp_t cdhp = cdh; 116 gp_t gp = g; // expected-error {{reference to __global__ function 'g' in __device__ function}} 117 // expected-note@67 {{'g' declared here}} 118 119 d(); 120 cd(); 121 h(); 122 ch(); 123 #if !defined(NOCHECKS) 124 // expected-error@-3 {{no matching function for call to 'h'}} 125 // expected-note@66 {{candidate function not viable: call to __host__ function from __device__ function}} 126 // expected-error@-4 {{no matching function for call to 'ch'}} 127 // expected-note@69 {{candidate function not viable: call to __host__ function from __device__ function}} 128 #endif 129 dh(); 130 cdh(); 131 g(); // expected-error {{no matching function for call to 'g'}} 132 // expected-note@67 {{candidate function not viable: call to __global__ function from __device__ function}} 133 g<<<0,0>>>(); // expected-error {{reference to __global__ function 'g' in __device__ function}} 134 // expected-note@67 {{'g' declared here}} 135 } 136 137 __global__ void globalf(void) { 138 fp_t dp = d; 139 fp_t cdp = cd; 140 fp_t hp = h; 141 fp_t chp = ch; 142 #if !defined(NOCHECKS) 143 // expected-error@-3 {{reference to __host__ function 'h' in __global__ function}} 144 // expected-note@66 {{'h' declared here}} 145 // expected-error@-4 {{reference to __host__ function 'ch' in __global__ function}} 146 // expected-note@69 {{'ch' declared here}} 147 #endif 148 fp_t dhp = dh; 149 fp_t cdhp = cdh; 150 gp_t gp = g; // expected-error {{reference to __global__ function 'g' in __global__ function}} 151 // expected-note@67 {{'g' declared here}} 152 153 d(); 154 cd(); 155 h(); 156 ch(); 157 #if !defined(NOCHECKS) 158 // expected-error@-3 {{no matching function for call to 'h'}} 159 // expected-note@66 {{candidate function not viable: call to __host__ function from __global__ function}} 160 // expected-error@-4 {{no matching function for call to 'ch'}} 161 // expected-note@69 {{candidate function not viable: call to __host__ function from __global__ function}} 162 #endif 163 dh(); 164 cdh(); 165 g(); // expected-error {{no matching function for call to 'g'}} 166 // expected-note@67 {{candidate function not viable: call to __global__ function from __global__ function}} 167 g<<<0,0>>>(); // expected-error {{reference to __global__ function 'g' in __global__ function}} 168 // expected-note@67 {{'g' declared here}} 169 } 170 171 __host__ __device__ void hostdevicef(void) { 172 fp_t dp = d; 173 fp_t cdp = cd; 174 fp_t hp = h; 175 fp_t chp = ch; 176 #if !defined(NOCHECKS) 177 #if !defined(__CUDA_ARCH__) 178 // expected-error@-6 {{reference to __device__ function 'd' in __host__ __device__ function}} 179 // expected-note@65 {{'d' declared here}} 180 // expected-error@-7 {{reference to __device__ function 'cd' in __host__ __device__ function}} 181 // expected-note@68 {{'cd' declared here}} 182 #else 183 // expected-error@-9 {{reference to __host__ function 'h' in __host__ __device__ function}} 184 // expected-note@66 {{'h' declared here}} 185 // expected-error@-10 {{reference to __host__ function 'ch' in __host__ __device__ function}} 186 // expected-note@69 {{'ch' declared here}} 187 #endif 188 #endif 189 fp_t dhp = dh; 190 fp_t cdhp = cdh; 191 gp_t gp = g; 192 #if defined(__CUDA_ARCH__) 193 // expected-error@-2 {{reference to __global__ function 'g' in __host__ __device__ function}} 194 // expected-note@67 {{'g' declared here}} 195 #endif 196 197 d(); 198 cd(); 199 h(); 200 ch(); 201 #if !defined(NOCHECKS) 202 #if !defined(__CUDA_ARCH__) 203 // expected-error@-6 {{no matching function for call to 'd'}} 204 // expected-note@65 {{candidate function not viable: call to __device__ function from __host__ __device__ function}} 205 // expected-error@-7 {{no matching function for call to 'cd'}} 206 // expected-note@68 {{candidate function not viable: call to __device__ function from __host__ __device__ function}} 207 #else 208 // expected-error@-9 {{no matching function for call to 'h'}} 209 // expected-note@66 {{candidate function not viable: call to __host__ function from __host__ __device__ function}} 210 // expected-error@-10 {{no matching function for call to 'ch'}} 211 // expected-note@69 {{candidate function not viable: call to __host__ function from __host__ __device__ function}} 212 #endif 213 #endif 214 215 dh(); 216 cdh(); 217 g(); 218 g<<<0,0>>>(); 219 #if !defined(__CUDA_ARCH__) 220 // expected-error@-3 {{call to global function g not configured}} 221 #else 222 // expected-error@-5 {{no matching function for call to 'g'}} 223 // expected-note@67 {{candidate function not viable: call to __global__ function from __host__ __device__ function}} 224 // expected-error@-6 {{reference to __global__ function 'g' in __host__ __device__ function}} 225 // expected-note@67 {{'g' declared here}} 226 #endif // __CUDA_ARCH__ 227 } 228 229 // Test for address of overloaded function resolution in the global context. 230 fp_t hp = h; 231 fp_t chp = ch; 232 fp_t dhp = dh; 233 fp_t cdhp = cdh; 234 gp_t gp = g; 235 236 237 // Test overloading of destructors 238 // Can't mix H and unattributed destructors 239 struct d_h { 240 ~d_h() {} // expected-note {{previous declaration is here}} 241 __host__ ~d_h() {} // expected-error {{destructor cannot be redeclared}} 242 }; 243 244 // H/D overloading is OK 245 struct d_dh { 246 __device__ ~d_dh() {} 247 __host__ ~d_dh() {} 248 }; 249 250 // HD is OK 251 struct d_hd { 252 __host__ __device__ ~d_hd() {} 253 }; 254 255 // Mixing H/D and HD is not allowed. 256 struct d_dhhd { 257 __device__ ~d_dhhd() {} 258 __host__ ~d_dhhd() {} // expected-note {{previous declaration is here}} 259 __host__ __device__ ~d_dhhd() {} // expected-error {{destructor cannot be redeclared}} 260 }; 261 262 struct d_hhd { 263 __host__ ~d_hhd() {} // expected-note {{previous declaration is here}} 264 __host__ __device__ ~d_hhd() {} // expected-error {{destructor cannot be redeclared}} 265 }; 266 267 struct d_hdh { 268 __host__ __device__ ~d_hdh() {} // expected-note {{previous declaration is here}} 269 __host__ ~d_hdh() {} // expected-error {{destructor cannot be redeclared}} 270 }; 271 272 struct d_dhd { 273 __device__ ~d_dhd() {} // expected-note {{previous declaration is here}} 274 __host__ __device__ ~d_dhd() {} // expected-error {{destructor cannot be redeclared}} 275 }; 276 277 struct d_hdd { 278 __host__ __device__ ~d_hdd() {} // expected-note {{previous declaration is here}} 279 __device__ ~d_hdd() {} // expected-error {{destructor cannot be redeclared}} 280 }; 281 282 // Test overloading of member functions 283 struct m_h { 284 void operator delete(void *ptr); // expected-note {{previous declaration is here}} 285 __host__ void operator delete(void *ptr); // expected-error {{class member cannot be redeclared}} 286 }; 287 288 // D/H overloading is OK 289 struct m_dh { 290 __device__ void operator delete(void *ptr); 291 __host__ void operator delete(void *ptr); 292 }; 293 294 // HD by itself is OK 295 struct m_hd { 296 __device__ __host__ void operator delete(void *ptr); 297 }; 298 299 struct m_hhd { 300 __host__ void operator delete(void *ptr) {} // expected-note {{previous declaration is here}} 301 __host__ __device__ void operator delete(void *ptr) {} // expected-error {{class member cannot be redeclared}} 302 }; 303 304 struct m_hdh { 305 __host__ __device__ void operator delete(void *ptr) {} // expected-note {{previous declaration is here}} 306 __host__ void operator delete(void *ptr) {} // expected-error {{class member cannot be redeclared}} 307 }; 308 309 struct m_dhd { 310 __device__ void operator delete(void *ptr) {} // expected-note {{previous declaration is here}} 311 __host__ __device__ void operator delete(void *ptr) {} // expected-error {{class member cannot be redeclared}} 312 }; 313 314 struct m_hdd { 315 __host__ __device__ void operator delete(void *ptr) {} // expected-note {{previous declaration is here}} 316 __device__ void operator delete(void *ptr) {} // expected-error {{class member cannot be redeclared}} 317 }; 318