1// { dg-do "run" }
2#include <cassert>
3
4struct A
5{
6  double a;
7  double b;
8};
9
10union U
11{
12  double a;
13  double b;
14};
15
16struct B
17{
18  ~B() { }
19};
20
21struct C
22: public B { };
23
24struct D
25: public A { };
26
27template<typename T>
28  bool
29  f()
30  { return __has_trivial_destructor(T); }
31
32template<typename T>
33  class My
34  {
35  public:
36    bool
37    f()
38    { return !!__has_trivial_destructor(T); }
39  };
40
41template<typename T>
42  class My2
43  {
44  public:
45    static const bool trait = __has_trivial_destructor(T);
46  };
47
48template<typename T>
49  const bool My2<T>::trait;
50
51template<typename T, bool b = __has_trivial_destructor(T)>
52  struct My3_help
53  { static const bool trait = b; };
54
55template<typename T, bool b>
56  const bool My3_help<T, b>::trait;
57
58template<typename T>
59  class My3
60  {
61  public:
62    bool
63    f()
64    { return My3_help<T>::trait; }
65  };
66
67#define PTEST(T) (__has_trivial_destructor(T) && f<T>() \
68                  && My<T>().f() && My2<T>::trait && My3<T>().f())
69
70#define NTEST(T) (!__has_trivial_destructor(T) && !f<T>() \
71                  && !My<T>().f() && !My2<T>::trait && !My3<T>().f())
72
73int main()
74{
75  assert (PTEST (int));
76  assert (NTEST (int (int)));
77  assert (NTEST (void));
78  assert (PTEST (A));
79  assert (PTEST (U));
80  assert (NTEST (B));
81  assert (NTEST (C));
82  assert (PTEST (D));
83  assert (PTEST (D[]));
84
85  return 0;
86}
87