summaryrefslogtreecommitdiff
path: root/test/FrontendC++/2010-03-22-empty-baseclass.cpp
blob: b6bdea40c3f2ec3c2bb4c53f4fb7d6f8e0395c40 (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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// RUN: %llvmgxx -S -emit-llvm %s -o - -O2 | FileCheck %s
namespace boost {
  namespace detail {
    template <typename T> struct cv_traits_imp {};
    template <typename T> struct cv_traits_imp<T*> {typedef T unqualified_type;};
  }
}
namespace mpl_ {}
namespace boost {
  namespace mpl {using namespace mpl_;}
  template< typename T > struct remove_cv {typedef typename boost::detail::cv_traits_imp<T*>::unqualified_type type;};
  namespace type_traits {
    typedef char yes_type;
    struct no_type {char padding[8];};
  }
}
namespace mpl_ {
  template< bool C_ > struct bool_;
  typedef bool_<true> true_;
  typedef bool_<false> false_;
  template< bool C_ > struct bool_ {static const bool value = C_;};
  template< typename T, T N > struct integral_c;
}
namespace boost{
  template <class T, T val>   struct integral_constant :
    public mpl::integral_c<T, val> {};
  template<> struct integral_constant<bool,true> : public mpl::true_ {};
  template<> struct integral_constant<bool,false> : public mpl::false_ {};
  namespace type_traits {
    template <bool b1, bool b2, bool b3 = false, bool b4 = false,
              bool b5 = false, bool b6 = false, bool b7 = false> struct ice_or;
    template <bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7>
    struct ice_or {static const bool value = true; };
    template <> struct ice_or<false, false, false, false, false, false, false>
    {static const bool value = false;};
    template <bool b1, bool b2, bool b3 = true, bool b4 = true, bool b5 = true,
              bool b6 = true, bool b7 = true> struct ice_and;
    template <bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7>
    struct ice_and {static const bool value = false;};
    template <> struct ice_and<true, true, true, true, true, true, true>
    {static const bool value = true;};
    template <bool b> struct ice_not {static const bool value = true;};
  };
  namespace detail {
    template <typename T> struct is_union_impl {static const bool value = false;};
  }
  template< typename T > struct is_union :
  ::boost::integral_constant<bool, ::boost::detail::is_union_impl<T>::value> {};
  namespace detail {
    template <class U> ::boost::type_traits::yes_type is_class_tester(void(U::*)(void));
    template <class U> ::boost::type_traits::no_type is_class_tester(...);
    template <typename T> struct is_class_impl {
      static const bool value = (::boost::type_traits::ice_and< sizeof(is_class_tester<T>(0))
                                 == sizeof(::boost::type_traits::yes_type),
                                 ::boost::type_traits::ice_not< ::boost::is_union<T>::value >::value >::value);};
}
  template<typename T> struct is_class:
  ::boost::integral_constant<bool,::boost::detail::is_class_impl<T>::value> {  };
namespace detail {
  template <typename T> struct empty_helper_t1: public T {int i[256];};
  struct empty_helper_t2 {int i[256];};
  template <typename T, bool is_a_class = false> struct empty_helper
  {static const bool value = false;};
  template <typename T> struct empty_helper<T, true>
  {static const bool value = (sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2));};
  template <typename T> struct is_empty_impl {
    typedef typename remove_cv<T>::type cvt;
    static const bool value = (::boost::type_traits::ice_or< ::boost::detail::empty_helper
                               <cvt,::boost::is_class<T>::value>::value, false>::value);
  };
}
template<typename T> struct is_empty:
::boost::integral_constant<bool,::boost::detail::is_empty_impl<T>::value> {};
template<typename T, typename U > struct is_same:
::boost::integral_constant<bool,false> {};
template<typename T> struct call_traits {typedef T& reference;};
namespace details {
  template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>
  struct compressed_pair_switch;
  template <class T1, class T2>
  struct compressed_pair_switch<T1, T2, false, true, false>
  {static const int value = 1;};
  template <class T1, class T2, int Version> class compressed_pair_imp;
  template <class T1, class T2> class compressed_pair_imp<T1, T2, 1>:
  protected ::boost::remove_cv<T1>::type {
  public:
    typedef T1 first_type;
    typedef T2 second_type;
    typedef typename call_traits<first_type>::reference first_reference;
    typedef typename call_traits<second_type>::reference second_reference;
    first_reference first() {return *this;}
    second_reference second() {return second_;}
    second_type second_;
  };
}
template <class T1, class T2> class compressed_pair:
  private ::boost::details::compressed_pair_imp<T1, T2, ::boost::details::compressed_pair_switch<
                                                          T1, T2, ::boost::is_same<typename remove_cv<T1>::type,
                                                                                   typename remove_cv<T2>::type>::value,
                                                          ::boost::is_empty<T1>::value, ::boost::is_empty<T2>::value>::value>
  {
  private:
    typedef details::compressed_pair_imp<T1, T2, ::boost::details::compressed_pair_switch<
                                                   T1, T2, ::boost::is_same<typename remove_cv<T1>::type,
                                                                            typename remove_cv<T2>::type>::value,
                                                                              ::boost::is_empty<T1>::value, ::boost::is_empty<T2>::value>::value> base;
  public:
    typedef T1 first_type;
    typedef T2 second_type;
    typedef typename call_traits<first_type>::reference first_reference;
    typedef typename call_traits<second_type>::reference second_reference;
    first_reference first() {return base::first();}
    second_reference second() {return base::second();}
  };
}
struct empty_base_t {};
struct empty_t : empty_base_t {};
typedef boost::compressed_pair<empty_t, int> data_t;
extern "C" {int printf(const char * , ...);}
extern "C" {void abort(void);}
int main (int argc, char * const argv[]) {
  data_t x;
  x.second() = -3;
  // This store should be elided:
  x.first() = empty_t();
  // If x.second() has been clobbered by the elided store, fail.
  if (x.second() != -3) {
    printf("x.second() was clobbered\n");
    // CHECK-NOT: x.second() was clobbered
    abort();
  }
  return 0;
}
// CHECK: ret i32