// RUN: %clang_cc1 -std=c++11 -fcuda-is-device -fsyntax-only -verify %s // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s #include "Inputs/cuda.h" #ifndef __CUDA_ARCH__ // expected-no-diagnostics #endif // When compiling for device, foo()'s call to host_fn() is an error, because // foo() is known-emitted. // // The trickiness here comes from the fact that the FunctionDecl bar() sees // foo() does not have the "inline" keyword, so we might incorrectly think that // foo() is a priori known-emitted. This would prevent us from marking foo() // as known-emitted when we see the call from bar() to foo(), which would // prevent us from emitting an error for foo()'s call to host_fn() when we // eventually see it. void host_fn() {} #ifdef __CUDA_ARCH__ // expected-note@-2 {{declared here}} #endif __host__ __device__ void foo(); __device__ void bar() { foo(); #ifdef __CUDA_ARCH__ // expected-note@-2 {{called by 'bar'}} #endif } inline __host__ __device__ void foo() { host_fn(); #ifdef __CUDA_ARCH__ // expected-error@-2 {{reference to __host__ function}} #endif } // This is similar to the above, except there's no error here. This code used // to trip an assertion due to us noticing, when emitting the definition of // boom(), that T::operator S() was (incorrectly) considered a priori // known-emitted. struct S {}; struct T { __device__ operator S() const; }; __device__ inline T::operator S() const { return S(); } __device__ T t; __device__ void boom() { S s = t; }