According to my auto-simplifier the most common missed simplifications in
[llvm/stm8.git] / test / FrontendC++ / 2010-03-22-empty-baseclass.cpp
blobbb741c42c842461d0c261f283533990ca892beaf
1 // RUN: %llvmgxx -S %s -o - -O2 | FileCheck %s
2 namespace boost {
3 namespace detail {
4 template <typename T> struct cv_traits_imp {};
5 template <typename T> struct cv_traits_imp<T*> {typedef T unqualified_type;};
8 namespace mpl_ {}
9 namespace boost {
10 namespace mpl {using namespace mpl_;}
11 template< typename T > struct remove_cv {typedef typename boost::detail::cv_traits_imp<T*>::unqualified_type type;};
12 namespace type_traits {
13 typedef char yes_type;
14 struct no_type {char padding[8];};
17 namespace mpl_ {
18 template< bool C_ > struct bool_;
19 typedef bool_<true> true_;
20 typedef bool_<false> false_;
21 template< bool C_ > struct bool_ {static const bool value = C_;};
22 template< typename T, T N > struct integral_c;
24 namespace boost{
25 template <class T, T val> struct integral_constant :
26 public mpl::integral_c<T, val> {};
27 template<> struct integral_constant<bool,true> : public mpl::true_ {};
28 template<> struct integral_constant<bool,false> : public mpl::false_ {};
29 namespace type_traits {
30 template <bool b1, bool b2, bool b3 = false, bool b4 = false,
31 bool b5 = false, bool b6 = false, bool b7 = false> struct ice_or;
32 template <bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7>
33 struct ice_or {static const bool value = true; };
34 template <> struct ice_or<false, false, false, false, false, false, false>
35 {static const bool value = false;};
36 template <bool b1, bool b2, bool b3 = true, bool b4 = true, bool b5 = true,
37 bool b6 = true, bool b7 = true> struct ice_and;
38 template <bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7>
39 struct ice_and {static const bool value = false;};
40 template <> struct ice_and<true, true, true, true, true, true, true>
41 {static const bool value = true;};
42 template <bool b> struct ice_not {static const bool value = true;};
44 namespace detail {
45 template <typename T> struct is_union_impl {static const bool value = false;};
47 template< typename T > struct is_union :
48 ::boost::integral_constant<bool, ::boost::detail::is_union_impl<T>::value> {};
49 namespace detail {
50 template <class U> ::boost::type_traits::yes_type is_class_tester(void(U::*)(void));
51 template <class U> ::boost::type_traits::no_type is_class_tester(...);
52 template <typename T> struct is_class_impl {
53 static const bool value = (::boost::type_traits::ice_and< sizeof(is_class_tester<T>(0))
54 == sizeof(::boost::type_traits::yes_type),
55 ::boost::type_traits::ice_not< ::boost::is_union<T>::value >::value >::value);};
57 template<typename T> struct is_class:
58 ::boost::integral_constant<bool,::boost::detail::is_class_impl<T>::value> { };
59 namespace detail {
60 template <typename T> struct empty_helper_t1: public T {int i[256];};
61 struct empty_helper_t2 {int i[256];};
62 template <typename T, bool is_a_class = false> struct empty_helper
63 {static const bool value = false;};
64 template <typename T> struct empty_helper<T, true>
65 {static const bool value = (sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2));};
66 template <typename T> struct is_empty_impl {
67 typedef typename remove_cv<T>::type cvt;
68 static const bool value = (::boost::type_traits::ice_or< ::boost::detail::empty_helper
69 <cvt,::boost::is_class<T>::value>::value, false>::value);
72 template<typename T> struct is_empty:
73 ::boost::integral_constant<bool,::boost::detail::is_empty_impl<T>::value> {};
74 template<typename T, typename U > struct is_same:
75 ::boost::integral_constant<bool,false> {};
76 template<typename T> struct call_traits {typedef T& reference;};
77 namespace details {
78 template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>
79 struct compressed_pair_switch;
80 template <class T1, class T2>
81 struct compressed_pair_switch<T1, T2, false, true, false>
82 {static const int value = 1;};
83 template <class T1, class T2, int Version> class compressed_pair_imp;
84 template <class T1, class T2> class compressed_pair_imp<T1, T2, 1>:
85 protected ::boost::remove_cv<T1>::type {
86 public:
87 typedef T1 first_type;
88 typedef T2 second_type;
89 typedef typename call_traits<first_type>::reference first_reference;
90 typedef typename call_traits<second_type>::reference second_reference;
91 first_reference first() {return *this;}
92 second_reference second() {return second_;}
93 second_type second_;
96 template <class T1, class T2> class compressed_pair:
97 private ::boost::details::compressed_pair_imp<T1, T2, ::boost::details::compressed_pair_switch<
98 T1, T2, ::boost::is_same<typename remove_cv<T1>::type,
99 typename remove_cv<T2>::type>::value,
100 ::boost::is_empty<T1>::value, ::boost::is_empty<T2>::value>::value>
102 private:
103 typedef details::compressed_pair_imp<T1, T2, ::boost::details::compressed_pair_switch<
104 T1, T2, ::boost::is_same<typename remove_cv<T1>::type,
105 typename remove_cv<T2>::type>::value,
106 ::boost::is_empty<T1>::value, ::boost::is_empty<T2>::value>::value> base;
107 public:
108 typedef T1 first_type;
109 typedef T2 second_type;
110 typedef typename call_traits<first_type>::reference first_reference;
111 typedef typename call_traits<second_type>::reference second_reference;
112 first_reference first() {return base::first();}
113 second_reference second() {return base::second();}
116 struct empty_base_t {};
117 struct empty_t : empty_base_t {};
118 typedef boost::compressed_pair<empty_t, int> data_t;
119 extern "C" {int printf(const char * , ...);}
120 extern "C" {void abort(void);}
121 int main (int argc, char * const argv[]) {
122 data_t x;
123 x.second() = -3;
124 // This store should be elided:
125 x.first() = empty_t();
126 // If x.second() has been clobbered by the elided store, fail.
127 if (x.second() != -3) {
128 printf("x.second() was clobbered\n");
129 // CHECK-NOT: x.second() was clobbered
130 abort();
132 return 0;
134 // CHECK: ret i32