blob: 782c13d5445f3f2dc4ba8f754100f2484bbfbba1 [file] [log] [blame]
Justin Lebar18e2d822016-08-15 23:00:49 +00001// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown -fcuda-is-device -emit-llvm -o - -verify
2
3// Note: This test won't work with -fsyntax-only, because some of these errors
4// are emitted during codegen.
5
6#include "Inputs/cuda.h"
7
8extern "C" void host_fn() {}
Justin Lebar26bb3112016-08-16 00:48:21 +00009// expected-note@-1 {{'host_fn' declared here}}
10// expected-note@-2 {{'host_fn' declared here}}
11// expected-note@-3 {{'host_fn' declared here}}
12// expected-note@-4 {{'host_fn' declared here}}
13// expected-note@-5 {{'host_fn' declared here}}
14// expected-note@-6 {{'host_fn' declared here}}
Justin Lebar9fdb46e2016-10-08 01:07:11 +000015// expected-note@-7 {{'host_fn' declared here}}
16
17struct Dummy {};
Justin Lebar18e2d822016-08-15 23:00:49 +000018
19struct S {
20 S() {}
Justin Lebar26bb3112016-08-16 00:48:21 +000021 // expected-note@-1 {{'S' declared here}}
22 // expected-note@-2 {{'S' declared here}}
Justin Lebar18e2d822016-08-15 23:00:49 +000023 ~S() { host_fn(); }
Justin Lebar26bb3112016-08-16 00:48:21 +000024 // expected-note@-1 {{'~S' declared here}}
Justin Lebar18e2d822016-08-15 23:00:49 +000025 int x;
26};
27
28struct T {
29 __host__ __device__ void hd() { host_fn(); }
30 // expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
31
32 // No error; this is (implicitly) inline and is never called, so isn't
33 // codegen'ed.
34 __host__ __device__ void hd2() { host_fn(); }
35
36 __host__ __device__ void hd3();
37
38 void h() {}
Justin Lebar26bb3112016-08-16 00:48:21 +000039 // expected-note@-1 {{'h' declared here}}
Justin Lebar9fdb46e2016-10-08 01:07:11 +000040
41 void operator+();
42 // expected-note@-1 {{'operator+' declared here}}
43
44 void operator-(const T&) {}
45 // expected-note@-1 {{'operator-' declared here}}
46
47 operator Dummy() { return Dummy(); }
48 // expected-note@-1 {{'operator Dummy' declared here}}
Justin Lebar18e2d822016-08-15 23:00:49 +000049};
50
51__host__ __device__ void T::hd3() {
52 host_fn();
53 // expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
54}
55
56template <typename T> __host__ __device__ void hd2() { host_fn(); }
57// expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
58__global__ void kernel() { hd2<int>(); }
59
60__host__ __device__ void hd() { host_fn(); }
61// expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
62
63template <typename T> __host__ __device__ void hd3() { host_fn(); }
64// expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
65__device__ void device_fn() { hd3<int>(); }
66
67// No error because this is never instantiated.
68template <typename T> __host__ __device__ void hd4() { host_fn(); }
69
70__host__ __device__ void local_var() {
71 S s;
72 // expected-error@-1 {{reference to __host__ function 'S' in __host__ __device__ function}}
73}
74
75__host__ __device__ void placement_new(char *ptr) {
76 ::new(ptr) S();
77 // expected-error@-1 {{reference to __host__ function 'S' in __host__ __device__ function}}
78}
79
80__host__ __device__ void explicit_destructor(S *s) {
81 s->~S();
82 // expected-error@-1 {{reference to __host__ function '~S' in __host__ __device__ function}}
83}
84
85__host__ __device__ void hd_member_fn() {
86 T t;
87 // Necessary to trigger an error on T::hd. It's (implicitly) inline, so
88 // isn't codegen'ed until we call it.
89 t.hd();
90}
91
92__host__ __device__ void h_member_fn() {
93 T t;
94 t.h();
95 // expected-error@-1 {{reference to __host__ function 'h' in __host__ __device__ function}}
96}
97
98__host__ __device__ void fn_ptr() {
99 auto* ptr = &host_fn;
100 // expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
101}
102
103template <typename T>
104__host__ __device__ void fn_ptr_template() {
105 auto* ptr = &host_fn; // Not an error because the template isn't instantiated.
106}
Justin Lebar9fdb46e2016-10-08 01:07:11 +0000107
108__host__ __device__ void unaryOp() {
109 T t;
110 (void) +t; // expected-error {{reference to __host__ function 'operator+' in __host__ __device__ function}}
111}
112
113__host__ __device__ void binaryOp() {
114 T t;
115 (void) (t - t); // expected-error {{reference to __host__ function 'operator-' in __host__ __device__ function}}
116}
117
118__host__ __device__ void implicitConversion() {
119 T t;
120 Dummy d = t; // expected-error {{reference to __host__ function 'operator Dummy' in __host__ __device__ function}}
121}
122
123template <typename T>
124struct TmplStruct {
125 template <typename U> __host__ __device__ void fn() {}
126};
127
128template <>
129template <>
130__host__ __device__ void TmplStruct<int>::fn<int>() { host_fn(); }
131// expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
132
133__device__ void double_specialization() { TmplStruct<int>().fn<int>(); }