blob: dc22722610154f6f3d20dfeb0563c67e5ff0dcea [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 Lebar26bb3112016-08-16 00:48:21 +000010// expected-note@-1 {{'device_fn' declared here}}
11// expected-note@-2 {{'device_fn' declared here}}
12// expected-note@-3 {{'device_fn' declared here}}
13// expected-note@-4 {{'device_fn' declared here}}
14// expected-note@-5 {{'device_fn' declared here}}
Justin Lebar18e2d822016-08-15 23:00:49 +000015
16struct S {
17 __device__ S() {}
Justin Lebar26bb3112016-08-16 00:48:21 +000018 // expected-note@-1 {{'S' declared here}}
19 // expected-note@-2 {{'S' declared here}}
Justin Lebar18e2d822016-08-15 23:00:49 +000020 __device__ ~S() { device_fn(); }
Justin Lebar26bb3112016-08-16 00:48:21 +000021 // expected-note@-1 {{'~S' declared here}}
Justin Lebar18e2d822016-08-15 23:00:49 +000022 int x;
23};
24
25struct T {
26 __host__ __device__ void hd() { device_fn(); }
27 // expected-error@-1 {{reference to __device__ function 'device_fn' in __host__ __device__ function}}
28
29 // No error; this is (implicitly) inline and is never called, so isn't
30 // codegen'ed.
31 __host__ __device__ void hd2() { device_fn(); }
32
33 __host__ __device__ void hd3();
34
35 __device__ void d() {}
Justin Lebar26bb3112016-08-16 00:48:21 +000036 // expected-note@-1 {{'d' declared here}}
Justin Lebar18e2d822016-08-15 23:00:49 +000037};
38
39__host__ __device__ void T::hd3() {
40 device_fn();
41 // expected-error@-1 {{reference to __device__ function 'device_fn' in __host__ __device__ function}}
42}
43
44template <typename T> __host__ __device__ void hd2() { device_fn(); }
45// expected-error@-1 {{reference to __device__ function 'device_fn' in __host__ __device__ function}}
46void host_fn() { hd2<int>(); }
47
48__host__ __device__ void hd() { device_fn(); }
49// expected-error@-1 {{reference to __device__ function 'device_fn' in __host__ __device__ function}}
50
51// No error because this is never instantiated.
52template <typename T> __host__ __device__ void hd3() { device_fn(); }
53
54__host__ __device__ void local_var() {
55 S s;
56 // expected-error@-1 {{reference to __device__ function 'S' in __host__ __device__ function}}
57}
58
59__host__ __device__ void placement_new(char *ptr) {
60 ::new(ptr) S();
61 // expected-error@-1 {{reference to __device__ function 'S' in __host__ __device__ function}}
62}
63
64__host__ __device__ void explicit_destructor(S *s) {
65 s->~S();
66 // expected-error@-1 {{reference to __device__ function '~S' in __host__ __device__ function}}
67}
68
69__host__ __device__ void hd_member_fn() {
70 T t;
71 // Necessary to trigger an error on T::hd. It's (implicitly) inline, so
72 // isn't codegen'ed until we call it.
73 t.hd();
74}
75
76__host__ __device__ void h_member_fn() {
77 T t;
78 t.d();
79 // expected-error@-1 {{reference to __device__ function 'd' in __host__ __device__ function}}
80}
81
82__host__ __device__ void fn_ptr() {
83 auto* ptr = &device_fn;
84 // expected-error@-1 {{reference to __device__ function 'device_fn' in __host__ __device__ function}}
85}
86
87template <typename T>
88__host__ __device__ void fn_ptr_template() {
89 auto* ptr = &device_fn; // Not an error because the template isn't instantiated.
90}