|
@@ -0,0 +1,52 @@
|
|
|
+// 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;
|
|
|
+}
|