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