From b2dc2df7d2c8eccb1aecfc09726b69dcd9aba28f Mon Sep 17 00:00:00 2001 From: Stuart Hastings Date: Tue, 23 Mar 2010 18:39:23 +0000 Subject: [PATCH] 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 --- .../2010-03-22-empty-baseclass.cpp | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 test/FrontendC++/2010-03-22-empty-baseclass.cpp 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 00000000000..b6bdea40c3f --- /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 struct cv_traits_imp {}; + template struct cv_traits_imp {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::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_; + typedef bool_ false_; + template< bool C_ > struct bool_ {static const bool value = C_;}; + template< typename T, T N > struct integral_c; +} +namespace boost{ + template struct integral_constant : + public mpl::integral_c {}; + template<> struct integral_constant : public mpl::true_ {}; + template<> struct integral_constant : public mpl::false_ {}; + namespace type_traits { + template struct ice_or; + template + struct ice_or {static const bool value = true; }; + template <> struct ice_or + {static const bool value = false;}; + template struct ice_and; + template + struct ice_and {static const bool value = false;}; + template <> struct ice_and + {static const bool value = true;}; + template struct ice_not {static const bool value = true;}; + }; + namespace detail { + template struct is_union_impl {static const bool value = false;}; + } + template< typename T > struct is_union : + ::boost::integral_constant::value> {}; + namespace detail { + template ::boost::type_traits::yes_type is_class_tester(void(U::*)(void)); + template ::boost::type_traits::no_type is_class_tester(...); + template struct is_class_impl { + static const bool value = (::boost::type_traits::ice_and< sizeof(is_class_tester(0)) + == sizeof(::boost::type_traits::yes_type), + ::boost::type_traits::ice_not< ::boost::is_union::value >::value >::value);}; +} + template struct is_class: + ::boost::integral_constant::value> { }; +namespace detail { + template struct empty_helper_t1: public T {int i[256];}; + struct empty_helper_t2 {int i[256];}; + template struct empty_helper + {static const bool value = false;}; + template struct empty_helper + {static const bool value = (sizeof(empty_helper_t1) == sizeof(empty_helper_t2));}; + template struct is_empty_impl { + typedef typename remove_cv::type cvt; + static const bool value = (::boost::type_traits::ice_or< ::boost::detail::empty_helper + ::value>::value, false>::value); + }; +} +template struct is_empty: +::boost::integral_constant::value> {}; +template struct is_same: +::boost::integral_constant {}; +template struct call_traits {typedef T& reference;}; +namespace details { + template + struct compressed_pair_switch; + template + struct compressed_pair_switch + {static const int value = 1;}; + template class compressed_pair_imp; + template class compressed_pair_imp: + protected ::boost::remove_cv::type { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + first_reference first() {return *this;} + second_reference second() {return second_;} + second_type second_; + }; +} +template class compressed_pair: + private ::boost::details::compressed_pair_imp::type, + typename remove_cv::type>::value, + ::boost::is_empty::value, ::boost::is_empty::value>::value> + { + private: + typedef details::compressed_pair_imp::type, + typename remove_cv::type>::value, + ::boost::is_empty::value, ::boost::is_empty::value>::value> base; + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::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 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