blob: b83beba58db91f0bffb527dd256e481c67d51747 [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}}
Richard Smithf75dcbe2016-10-11 00:21:10 +000049
50 __host__ void operator delete(void*);
51 __device__ void operator delete(void*, size_t);
52};
53
54struct U {
55 __device__ void operator delete(void*, size_t) = delete;
56 __host__ __device__ void operator delete(void*);
Justin Lebar18e2d822016-08-15 23:00:49 +000057};
58
59__host__ __device__ void T::hd3() {
60 host_fn();
61 // expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
62}
63
64template <typename T> __host__ __device__ void hd2() { host_fn(); }
65// expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
66__global__ void kernel() { hd2<int>(); }
67
68__host__ __device__ void hd() { host_fn(); }
69// expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
70
71template <typename T> __host__ __device__ void hd3() { host_fn(); }
72// expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
73__device__ void device_fn() { hd3<int>(); }
74
75// No error because this is never instantiated.
76template <typename T> __host__ __device__ void hd4() { host_fn(); }
77
78__host__ __device__ void local_var() {
79 S s;
80 // expected-error@-1 {{reference to __host__ function 'S' in __host__ __device__ function}}
81}
82
83__host__ __device__ void placement_new(char *ptr) {
84 ::new(ptr) S();
85 // expected-error@-1 {{reference to __host__ function 'S' in __host__ __device__ function}}
86}
87
88__host__ __device__ void explicit_destructor(S *s) {
89 s->~S();
90 // expected-error@-1 {{reference to __host__ function '~S' in __host__ __device__ function}}
91}
92
Richard Smithf75dcbe2016-10-11 00:21:10 +000093__host__ __device__ void class_specific_delete(T *t, U *u) {
94 delete t; // ok, call sized device delete even though host has preferable non-sized version
95 delete u; // ok, call non-sized HD delete rather than sized D delete
96}
97
Justin Lebar18e2d822016-08-15 23:00:49 +000098__host__ __device__ void hd_member_fn() {
99 T t;
100 // Necessary to trigger an error on T::hd. It's (implicitly) inline, so
101 // isn't codegen'ed until we call it.
102 t.hd();
103}
104
105__host__ __device__ void h_member_fn() {
106 T t;
107 t.h();
108 // expected-error@-1 {{reference to __host__ function 'h' in __host__ __device__ function}}
109}
110
111__host__ __device__ void fn_ptr() {
112 auto* ptr = &host_fn;
113 // expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
114}
115
116template <typename T>
117__host__ __device__ void fn_ptr_template() {
118 auto* ptr = &host_fn; // Not an error because the template isn't instantiated.
119}
Justin Lebar9fdb46e2016-10-08 01:07:11 +0000120
121__host__ __device__ void unaryOp() {
122 T t;
123 (void) +t; // expected-error {{reference to __host__ function 'operator+' in __host__ __device__ function}}
124}
125
126__host__ __device__ void binaryOp() {
127 T t;
128 (void) (t - t); // expected-error {{reference to __host__ function 'operator-' in __host__ __device__ function}}
129}
130
131__host__ __device__ void implicitConversion() {
132 T t;
133 Dummy d = t; // expected-error {{reference to __host__ function 'operator Dummy' in __host__ __device__ function}}
134}
135
136template <typename T>
137struct TmplStruct {
138 template <typename U> __host__ __device__ void fn() {}
139};
140
141template <>
142template <>
143__host__ __device__ void TmplStruct<int>::fn<int>() { host_fn(); }
144// expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
145
146__device__ void double_specialization() { TmplStruct<int>().fn<int>(); }