Home | History | Annotate | Download | only in FrontendC++
      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