summaryrefslogtreecommitdiff
path: root/test/SemaCUDA
diff options
context:
space:
mode:
authorJustin Lebar <jlebar@google.com>2016-10-13 20:52:12 +0000
committerJustin Lebar <jlebar@google.com>2016-10-13 20:52:12 +0000
commit45b902e6896fcf9db3e79c1e4a49424cb67c8447 (patch)
tree2ac1f1f9eeb7b1100c5dbaffdf14ce07ecbf2a18 /test/SemaCUDA
parent8af2f11fe87ef22ffcb33e5da8e8955b101cf6a2 (diff)
[CUDA] Emit deferred diagnostics during Sema rather than during codegen.
Summary: Emitting deferred diagnostics during codegen was a hack. It did work, but usability was poor, both for us as compiler devs and for users. We don't codegen if there are any sema errors, so for users this meant that they wouldn't see deferred errors if there were any non-deferred errors. For devs, this meant that we had to carefully split up our tests so that when we tested deferred errors, we didn't emit any non-deferred errors. This change moves checking for deferred errors into Sema. See the big comment in SemaCUDA.cpp for an overview of the idea. This checking adds overhead to compilation, because we have to maintain a partial call graph. As a result, this change makes deferred errors a CUDA-only concept (whereas before they were a general concept). If anyone else wants to use this framework for something other than CUDA, we can generalize at that time. This patch makes the minimal set of test changes -- after this lands, I'll go back through and do a cleanup of the tests that we no longer have to split up. Reviewers: rnk Subscribers: cfe-commits, rsmith, tra Differential Revision: https://reviews.llvm.org/D25541 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@284158 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaCUDA')
-rw-r--r--test/SemaCUDA/call-host-fn-from-device.cu3
-rw-r--r--test/SemaCUDA/function-overload.cu44
-rw-r--r--test/SemaCUDA/method-target.cu6
-rw-r--r--test/SemaCUDA/reference-to-kernel-fn.cu5
4 files changed, 48 insertions, 10 deletions
diff --git a/test/SemaCUDA/call-host-fn-from-device.cu b/test/SemaCUDA/call-host-fn-from-device.cu
index b83beba58d..bb6ea230fa 100644
--- a/test/SemaCUDA/call-host-fn-from-device.cu
+++ b/test/SemaCUDA/call-host-fn-from-device.cu
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown -fcuda-is-device -emit-llvm -o - -verify
+// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown -fcuda-is-device \
+// RUN: -emit-llvm -o /dev/null -verify
// Note: This test won't work with -fsyntax-only, because some of these errors
// are emitted during codegen.
diff --git a/test/SemaCUDA/function-overload.cu b/test/SemaCUDA/function-overload.cu
index 11e8bae126..4545a80875 100644
--- a/test/SemaCUDA/function-overload.cu
+++ b/test/SemaCUDA/function-overload.cu
@@ -170,18 +170,35 @@ __host__ __device__ void hostdevicef() {
DeviceReturnTy ret_d = d();
DeviceFnPtr fp_cd = cd;
DeviceReturnTy ret_cd = cd();
+#if !defined(__CUDA_ARCH__)
+ // expected-error@-5 {{reference to __device__ function 'd' in __host__ __device__ function}}
+ // expected-error@-5 {{reference to __device__ function 'd' in __host__ __device__ function}}
+ // expected-error@-5 {{reference to __device__ function 'cd' in __host__ __device__ function}}
+ // expected-error@-5 {{reference to __device__ function 'cd' in __host__ __device__ function}}
+#endif
HostFnPtr fp_h = h;
HostReturnTy ret_h = h();
HostFnPtr fp_ch = ch;
HostReturnTy ret_ch = ch();
+#if defined(__CUDA_ARCH__)
+ // expected-error@-5 {{reference to __host__ function 'h' in __host__ __device__ function}}
+ // expected-error@-5 {{reference to __host__ function 'h' in __host__ __device__ function}}
+ // expected-error@-5 {{reference to __host__ function 'ch' in __host__ __device__ function}}
+ // expected-error@-5 {{reference to __host__ function 'ch' in __host__ __device__ function}}
+#endif
CurrentFnPtr fp_dh = dh;
CurrentReturnTy ret_dh = dh();
CurrentFnPtr fp_cdh = cdh;
CurrentReturnTy ret_cdh = cdh();
- g(); // expected-error {{call to global function g not configured}}
+ g();
+#if defined (__CUDA_ARCH__)
+ // expected-error@-2 {{reference to __global__ function 'g' in __host__ __device__ function}}
+#else
+ // expected-error@-4 {{call to global function g not configured}}
+#endif
}
// Test for address of overloaded function resolution in the global context.
@@ -297,7 +314,11 @@ __device__ void test_device_calls_template_fn() {
// If we have a mix of HD and H-only or D-only candidates in the overload set,
// normal C++ overload resolution rules apply first.
-template <typename T> TemplateReturnTy template_vs_hd_function(T arg) {
+template <typename T> TemplateReturnTy template_vs_hd_function(T arg)
+#ifdef __CUDA_ARCH__
+//expected-note@-2 {{declared here}}
+#endif
+{
return TemplateReturnTy();
}
__host__ __device__ HostDeviceReturnTy template_vs_hd_function(float arg) {
@@ -307,6 +328,9 @@ __host__ __device__ HostDeviceReturnTy template_vs_hd_function(float arg) {
__host__ __device__ void test_host_device_calls_hd_template() {
HostDeviceReturnTy ret1 = template_vs_hd_function(1.0f);
TemplateReturnTy ret2 = template_vs_hd_function(1);
+#ifdef __CUDA_ARCH__
+ // expected-error@-2 {{reference to __host__ function 'template_vs_hd_function<int>' in __host__ __device__ function}}
+#endif
}
__host__ void test_host_calls_hd_template() {
@@ -326,14 +350,30 @@ __device__ void test_device_calls_hd_template() {
// side of compilation.
__device__ DeviceReturnTy device_only_function(int arg) { return DeviceReturnTy(); }
__device__ DeviceReturnTy2 device_only_function(float arg) { return DeviceReturnTy2(); }
+#ifndef __CUDA_ARCH__
+ // expected-note@-3 {{'device_only_function' declared here}}
+ // expected-note@-3 {{'device_only_function' declared here}}
+#endif
__host__ HostReturnTy host_only_function(int arg) { return HostReturnTy(); }
__host__ HostReturnTy2 host_only_function(float arg) { return HostReturnTy2(); }
+#ifdef __CUDA_ARCH__
+ // expected-note@-3 {{'host_only_function' declared here}}
+ // expected-note@-3 {{'host_only_function' declared here}}
+#endif
__host__ __device__ void test_host_device_single_side_overloading() {
DeviceReturnTy ret1 = device_only_function(1);
DeviceReturnTy2 ret2 = device_only_function(1.0f);
+#ifndef __CUDA_ARCH__
+ // expected-error@-3 {{reference to __device__ function 'device_only_function' in __host__ __device__ function}}
+ // expected-error@-3 {{reference to __device__ function 'device_only_function' in __host__ __device__ function}}
+#endif
HostReturnTy ret3 = host_only_function(1);
HostReturnTy2 ret4 = host_only_function(1.0f);
+#ifdef __CUDA_ARCH__
+ // expected-error@-3 {{reference to __host__ function 'host_only_function' in __host__ __device__ function}}
+ // expected-error@-3 {{reference to __host__ function 'host_only_function' in __host__ __device__ function}}
+#endif
}
// Verify that we allow overloading function templates.
diff --git a/test/SemaCUDA/method-target.cu b/test/SemaCUDA/method-target.cu
index 505664586b..8e17daa0c1 100644
--- a/test/SemaCUDA/method-target.cu
+++ b/test/SemaCUDA/method-target.cu
@@ -29,7 +29,7 @@ __device__ void foo2(S2& s, int i, float f) {
// Test 3: device method called from host function
struct S3 {
- __device__ void method() {} // expected-note {{'method' declared here}};
+ __device__ void method() {} // expected-note {{'method' declared here}}
};
void foo3(S3& s) {
@@ -40,11 +40,11 @@ void foo3(S3& s) {
// Test 4: device method called from host&device function
struct S4 {
- __device__ void method() {}
+ __device__ void method() {} // expected-note {{'method' declared here}}
};
__host__ __device__ void foo4(S4& s) {
- s.method();
+ s.method(); // expected-error {{reference to __device__ function 'method' in __host__ __device__ function}}
}
//------------------------------------------------------------------------------
diff --git a/test/SemaCUDA/reference-to-kernel-fn.cu b/test/SemaCUDA/reference-to-kernel-fn.cu
index 2d25dde94f..e502d134b0 100644
--- a/test/SemaCUDA/reference-to-kernel-fn.cu
+++ b/test/SemaCUDA/reference-to-kernel-fn.cu
@@ -18,10 +18,7 @@ typedef void (*fn_ptr_t)();
__host__ __device__ fn_ptr_t get_ptr_hd() {
return kernel;
#ifdef DEVICE
- // This emits a deferred error on the device, but we don't catch it in this
- // file because the non-deferred error below precludes this.
-
- // FIXME-expected-error@-2 {{reference to __global__ function}}
+ // expected-error@-2 {{reference to __global__ function}}
#endif
}
__host__ fn_ptr_t get_ptr_h() {