xref: /llvm-project/clang/test/SemaCUDA/implicit-device-lambda.cu (revision 9275e14379961a4304de559f16fdbac275fb6301)
1*9275e143SYaxun (Sam) Liu // RUN: %clang_cc1 -std=c++11 -fcuda-is-device -verify=dev,expected -fsyntax-only \
2*9275e143SYaxun (Sam) Liu // RUN:   -verify-ignore-unexpected=warning -verify-ignore-unexpected=note %s
3*9275e143SYaxun (Sam) Liu // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only \
4*9275e143SYaxun (Sam) Liu // RUN:   -verify-ignore-unexpected=warning -verify-ignore-unexpected=note %s
57ca116caSJustin Lebar 
67ca116caSJustin Lebar #include "Inputs/cuda.h"
77ca116caSJustin Lebar 
device_fn()87ca116caSJustin Lebar __device__ void device_fn() {
97ca116caSJustin Lebar   auto f1 = [&] {};
107ca116caSJustin Lebar   f1(); // implicitly __device__
117ca116caSJustin Lebar 
127ca116caSJustin Lebar   auto f2 = [&] __device__ {};
137ca116caSJustin Lebar   f2();
147ca116caSJustin Lebar 
157ca116caSJustin Lebar   auto f3 = [&] __host__ {};
167ca116caSJustin Lebar   f3();  // expected-error {{no matching function}}
177ca116caSJustin Lebar 
187ca116caSJustin Lebar   auto f4 = [&] __host__ __device__ {};
197ca116caSJustin Lebar   f4();
207ca116caSJustin Lebar 
217ca116caSJustin Lebar   // Now do it all again with '()'s in the lambda declarations: This is a
227ca116caSJustin Lebar   // different parse path.
237ca116caSJustin Lebar   auto g1 = [&]() {};
247ca116caSJustin Lebar   g1(); // implicitly __device__
257ca116caSJustin Lebar 
267ca116caSJustin Lebar   auto g2 = [&]() __device__ {};
277ca116caSJustin Lebar   g2();
287ca116caSJustin Lebar 
297ca116caSJustin Lebar   auto g3 = [&]() __host__ {};
307ca116caSJustin Lebar   g3();  // expected-error {{no matching function}}
317ca116caSJustin Lebar 
327ca116caSJustin Lebar   auto g4 = [&]() __host__ __device__ {};
337ca116caSJustin Lebar   g4();
347ca116caSJustin Lebar 
357ca116caSJustin Lebar   // Once more, with the '()'s in a different place.
367ca116caSJustin Lebar   auto h1 = [&]() {};
377ca116caSJustin Lebar   h1(); // implicitly __device__
387ca116caSJustin Lebar 
397ca116caSJustin Lebar   auto h2 = [&] __device__ () {};
407ca116caSJustin Lebar   h2();
417ca116caSJustin Lebar 
427ca116caSJustin Lebar   auto h3 = [&] __host__ () {};
437ca116caSJustin Lebar   h3();  // expected-error {{no matching function}}
447ca116caSJustin Lebar 
457ca116caSJustin Lebar   auto h4 = [&] __host__ __device__ () {};
467ca116caSJustin Lebar   h4();
477ca116caSJustin Lebar }
487ca116caSJustin Lebar 
497ca116caSJustin Lebar // Behaves identically to device_fn.
kernel_fn()507ca116caSJustin Lebar __global__ void kernel_fn() {
517ca116caSJustin Lebar   auto f1 = [&] {};
527ca116caSJustin Lebar   f1(); // implicitly __device__
537ca116caSJustin Lebar 
547ca116caSJustin Lebar   auto f2 = [&] __device__ {};
557ca116caSJustin Lebar   f2();
567ca116caSJustin Lebar 
577ca116caSJustin Lebar   auto f3 = [&] __host__ {};
587ca116caSJustin Lebar   f3();  // expected-error {{no matching function}}
597ca116caSJustin Lebar 
607ca116caSJustin Lebar   auto f4 = [&] __host__ __device__ {};
617ca116caSJustin Lebar   f4();
627ca116caSJustin Lebar 
637ca116caSJustin Lebar   // No need to re-test all the parser contortions we test in the device
647ca116caSJustin Lebar   // function.
657ca116caSJustin Lebar }
667ca116caSJustin Lebar 
host_fn()677ca116caSJustin Lebar __host__ void host_fn() {
687ca116caSJustin Lebar   auto f1 = [&] {};
697ca116caSJustin Lebar   f1(); // implicitly __host__ (i.e., no magic)
707ca116caSJustin Lebar 
717ca116caSJustin Lebar   auto f2 = [&] __device__ {};
727ca116caSJustin Lebar   f2();  // expected-error {{no matching function}}
737ca116caSJustin Lebar 
747ca116caSJustin Lebar   auto f3 = [&] __host__ {};
757ca116caSJustin Lebar   f3();
767ca116caSJustin Lebar 
777ca116caSJustin Lebar   auto f4 = [&] __host__ __device__ {};
787ca116caSJustin Lebar   f4();
797ca116caSJustin Lebar }
807ca116caSJustin Lebar 
hd_fn()81d3fd70deSJustin Lebar __host__ __device__ void hd_fn() {
82d3fd70deSJustin Lebar   auto f1 = [&] {};
83d3fd70deSJustin Lebar   f1(); // implicitly __host__ __device__
84d3fd70deSJustin Lebar 
85d3fd70deSJustin Lebar   auto f2 = [&] __device__ {};
86d3fd70deSJustin Lebar   f2();
87d3fd70deSJustin Lebar #ifndef __CUDA_ARCH__
88d3fd70deSJustin Lebar   // expected-error@-2 {{reference to __device__ function}}
89d3fd70deSJustin Lebar #endif
90d3fd70deSJustin Lebar 
91d3fd70deSJustin Lebar   auto f3 = [&] __host__ {};
92d3fd70deSJustin Lebar   f3();
93d3fd70deSJustin Lebar #ifdef __CUDA_ARCH__
94d3fd70deSJustin Lebar   // expected-error@-2 {{reference to __host__ function}}
95d3fd70deSJustin Lebar #endif
96d3fd70deSJustin Lebar 
97d3fd70deSJustin Lebar   auto f4 = [&] __host__ __device__ {};
98d3fd70deSJustin Lebar   f4();
99d3fd70deSJustin Lebar }
100d3fd70deSJustin Lebar 
1017ca116caSJustin Lebar // The special treatment above only applies to lambdas.
foo()1027ca116caSJustin Lebar __device__ void foo() {
1037ca116caSJustin Lebar   struct X {
1047ca116caSJustin Lebar     void foo() {}
1057ca116caSJustin Lebar   };
1067ca116caSJustin Lebar   X x;
107*9275e143SYaxun (Sam) Liu   x.foo(); // dev-error {{reference to __host__ function 'foo' in __device__ function}}
1087ca116caSJustin Lebar }
109