aboutsummaryrefslogtreecommitdiff
path: root/clang/test/SemaCUDA/dtor.cu
blob: cc37837e70791f93d07fda923f8cd19cfb2b019a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// RUN: %clang_cc1 %s -std=c++20 -fsyntax-only -verify=host
// RUN: %clang_cc1 %s -std=c++20 -fcuda-is-device -fsyntax-only -verify=dev

// host-no-diagnostics

#include "Inputs/cuda.h"

// Virtual dtor ~B() of explicit instantiation B<float> must
// be emitted, which causes host_fun() called.
namespace ExplicitInstantiationExplicitDevDtor {
void host_fun() // dev-note {{'host_fun' declared here}}
{}

template <unsigned>
constexpr void hd_fun() {
  host_fun(); // dev-error {{reference to __host__ function 'host_fun' in __host__ __device__ function}}
}

struct A {
  constexpr ~A() { // dev-note {{called by '~B'}}
     hd_fun<8>(); // dev-note {{called by '~A'}}
  }
};

template <typename T>
struct B {
public:
  virtual __device__ ~B() = default;
  A _a;
};

template class B<float>;
}

// The implicit host/device attrs of virtual dtor ~B() should be
// conservatively inferred, where constexpr member dtor's should
// not be considered device since they may call host functions.
// Therefore B<float>::~B() should not have implicit device attr.
// However C<float>::~C() should have implicit device attr since
// it is trivial.
namespace ExplicitInstantiationDtorNoAttr {
void host_fun()
{}

template <unsigned>
constexpr void hd_fun() {
  host_fun();
}

struct A {
  constexpr ~A() {
     hd_fun<8>();
  }
};

template <typename T>
struct B {
public:
  virtual ~B() = default;
  A _a;
};

template <typename T>
struct C {
public:
  virtual ~C() = default;
};

template class B<float>;
template class C<float>;
__device__ void foo() {
  C<float> x;
}
}

// Dtors of implicit template class instantiation are not
// conservatively inferred because the invalid usage can
// be diagnosed.
namespace ImplicitInstantiation {
void host_fun() // dev-note {{'host_fun' declared here}}
{}

template <unsigned>
constexpr void hd_fun() {
  host_fun(); // dev-error {{reference to __host__ function 'host_fun' in __host__ __device__ function}}
}

struct A {
  constexpr ~A() { // dev-note {{called by '~B'}}
     hd_fun<8>(); // dev-note {{called by '~A'}}
  }
};

template <typename T>
struct B {
public:
  ~B() = default; // dev-note {{called by 'foo'}}
  A _a;
};

__device__ void foo() {
  B<float> x;
}
}