blob: 3ea013f3a742af0a747074d25b6e4500b7cee035 [file] [log] [blame]
Justin Lebar6c86e912016-10-19 21:15:01 +00001// RUN: %clang_cc1 %s --std=c++11 -triple x86_64-unknown-linux -emit-llvm -o - \
2// RUN: -verify -verify-ignore-unexpected=note
Justin Lebar18e2d822016-08-15 23:00:49 +00003
4// Note: This test won't work with -fsyntax-only, because some of these errors
5// are emitted during codegen.
6
7#include "Inputs/cuda.h"
8
9__device__ void device_fn() {}
Justin Lebar4d38a5c2016-10-21 20:50:47 +000010// expected-note@-1 5 {{'device_fn' declared here}}
Justin Lebar18e2d822016-08-15 23:00:49 +000011
12struct S {
13 __device__ S() {}
Justin Lebar4d38a5c2016-10-21 20:50:47 +000014 // expected-note@-1 2 {{'S' declared here}}
Justin Lebar18e2d822016-08-15 23:00:49 +000015 __device__ ~S() { device_fn(); }
Justin Lebar26bb3112016-08-16 00:48:21 +000016 // expected-note@-1 {{'~S' declared here}}
Justin Lebar18e2d822016-08-15 23:00:49 +000017 int x;
18};
19
20struct T {
21 __host__ __device__ void hd() { device_fn(); }
22 // expected-error@-1 {{reference to __device__ function 'device_fn' in __host__ __device__ function}}
23
24 // No error; this is (implicitly) inline and is never called, so isn't
25 // codegen'ed.
26 __host__ __device__ void hd2() { device_fn(); }
27
28 __host__ __device__ void hd3();
29
30 __device__ void d() {}
Justin Lebar26bb3112016-08-16 00:48:21 +000031 // expected-note@-1 {{'d' declared here}}
Justin Lebar18e2d822016-08-15 23:00:49 +000032};
33
34__host__ __device__ void T::hd3() {
35 device_fn();
36 // expected-error@-1 {{reference to __device__ function 'device_fn' in __host__ __device__ function}}
37}
38
39template <typename T> __host__ __device__ void hd2() { device_fn(); }
40// expected-error@-1 {{reference to __device__ function 'device_fn' in __host__ __device__ function}}
41void host_fn() { hd2<int>(); }
42
43__host__ __device__ void hd() { device_fn(); }
44// expected-error@-1 {{reference to __device__ function 'device_fn' in __host__ __device__ function}}
45
46// No error because this is never instantiated.
47template <typename T> __host__ __device__ void hd3() { device_fn(); }
48
49__host__ __device__ void local_var() {
50 S s;
51 // expected-error@-1 {{reference to __device__ function 'S' in __host__ __device__ function}}
52}
53
54__host__ __device__ void placement_new(char *ptr) {
55 ::new(ptr) S();
56 // expected-error@-1 {{reference to __device__ function 'S' in __host__ __device__ function}}
57}
58
59__host__ __device__ void explicit_destructor(S *s) {
60 s->~S();
61 // expected-error@-1 {{reference to __device__ function '~S' in __host__ __device__ function}}
62}
63
64__host__ __device__ void hd_member_fn() {
65 T t;
66 // Necessary to trigger an error on T::hd. It's (implicitly) inline, so
67 // isn't codegen'ed until we call it.
68 t.hd();
69}
70
71__host__ __device__ void h_member_fn() {
72 T t;
73 t.d();
74 // expected-error@-1 {{reference to __device__ function 'd' in __host__ __device__ function}}
75}
76
77__host__ __device__ void fn_ptr() {
78 auto* ptr = &device_fn;
79 // expected-error@-1 {{reference to __device__ function 'device_fn' in __host__ __device__ function}}
80}
81
82template <typename T>
83__host__ __device__ void fn_ptr_template() {
84 auto* ptr = &device_fn; // Not an error because the template isn't instantiated.
85}