diff options
author | Stuart Hastings <stuart@apple.com> | 2010-03-23 18:39:23 +0000 |
---|---|---|
committer | Stuart Hastings <stuart@apple.com> | 2010-03-23 18:39:23 +0000 |
commit | b2dc2df7d2c8eccb1aecfc09726b69dcd9aba28f (patch) | |
tree | 0e26e79bc8a981c008712a519b60ce99aeb8440b | |
parent | 011355944bc914b556d43ca4e3b422049791de08 (diff) | |
download | external_llvm-b2dc2df7d2c8eccb1aecfc09726b69dcd9aba28f.zip external_llvm-b2dc2df7d2c8eccb1aecfc09726b69dcd9aba28f.tar.gz external_llvm-b2dc2df7d2c8eccb1aecfc09726b69dcd9aba28f.tar.bz2 |
Test case for llvm-gcc r99305. Radar 7659636.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99306 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | test/FrontendC++/2010-03-22-empty-baseclass.cpp | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/test/FrontendC++/2010-03-22-empty-baseclass.cpp b/test/FrontendC++/2010-03-22-empty-baseclass.cpp new file mode 100644 index 0000000..b6bdea4 --- /dev/null +++ b/test/FrontendC++/2010-03-22-empty-baseclass.cpp @@ -0,0 +1,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 |