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;}; 6 } 7 } 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];}; 15 } 16 } 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; 23 } 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;}; 43 }; 44 namespace detail { 45 template <typename T> struct is_union_impl {static const bool value = false;}; 46 } 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);}; 56 } 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); 70 }; 71 } 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_; 94 }; 95 } 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> 101 { 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();} 114 }; 115 } 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(); 131 } 132 return 0; 133 } 134 // CHECK: ret i32 135