• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // This test comes from upstream bug
2 // https://sourceware.org/bugzilla/show_bug.cgi?id=21296
3 //
4 // It has to be compiled once with clang++ and once with g++, like
5 // this:
6 //
7 // clang++ -std=c++14  -o test40-PR21296-libclang.so -shared -fPIC  test40-PR21296-clanggcc.cc  -g
8 //
9 // g++ -o test40-PR21296-libgcc.so -shared -fPIC test40-PR21296-clanggcc.cc -g
10 //
11 extern "C" void free(void*) throw ();
12 extern "C" char* strdup(const char*);
13 
14 struct STR {
STRSTR15    STR(const char* S): C(strdup(S)) {}
~STRSTR16    ~STR() { free(C); }
STRSTR17    STR(STR&& O): C(O.C) { O.C = 0; }
18    char* C;
19 };
20 
21 extern "C" int printf(const char*,...);
22 
23 namespace std
24 {
25 
26 typedef unsigned long size_t;
27 
28   struct true_type { static constexpr bool value = true; };
29   struct false_type { static constexpr bool value = false; };
30 
31   // Reference transformations.
32 
33   /// remove_reference
34   template<typename _Tp>
35     struct remove_reference
36     { typedef _Tp   type; };
37 
38   template<typename _Tp>
39     struct remove_reference<_Tp&>
40     { typedef _Tp   type; };
41 
42   template<typename _Tp>
43     struct remove_reference<_Tp&&>
44     { typedef _Tp   type; };
45 
46 
47   /**
48    *  @brief  Forward an lvalue.
49    *  @return The parameter cast to the specified type.
50    *
51    *  This function is used to implement "perfect forwarding".
52    */
53   template<typename _Tp>
54     constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type & __t)55     forward(typename std::remove_reference<_Tp>::type& __t) noexcept
56     { return static_cast<_Tp&&>(__t); }
57 
58   /**
59    *  @brief  Forward an rvalue.
60    *  @return The parameter cast to the specified type.
61    *
62    *  This function is used to implement "perfect forwarding".
63    */
64   template<typename _Tp>
65     constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type && __t)66     forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
67     {
68       return static_cast<_Tp&&>(__t);
69     }
70 
71   /**
72    *  @brief  Convert a value to an rvalue.
73    *  @param  __t  A thing of arbitrary type.
74    *  @return The parameter cast to an rvalue-reference to allow moving it.
75   */
76   template<typename _Tp>
77     constexpr typename std::remove_reference<_Tp>::type&&
move(_Tp && __t)78     move(_Tp&& __t) noexcept
79     { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
80 
81 
82   // Adds a const reference to a non-reference type.
83   template<typename _Tp>
84     struct __add_c_ref
85     { typedef const _Tp& type; };
86 
87   template<typename _Tp>
88     struct __add_c_ref<_Tp&>
89     { typedef _Tp& type; };
90 
91   template<std::size_t _Idx, typename _Head, bool _IsEmptyNotFinal>
92     struct _Head_base;
93 
94 
95   template<std::size_t _Idx, typename _Head>
96     struct _Head_base<_Idx, _Head, false>
97     {
_Head_basestd::_Head_base98       constexpr _Head_base()
99       : _M_head_impl() { }
100 
_Head_basestd::_Head_base101       constexpr _Head_base(const _Head& __h)
102       : _M_head_impl(__h) { }
103 
104       template<typename _UHead, typename = true_type>
_Head_basestd::_Head_base105         constexpr _Head_base(_UHead&& __h)
106 	: _M_head_impl(std::forward<_UHead>(__h)) { }
107 
108       static constexpr const _Head&
_M_headstd::_Head_base109       _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
110 
111       _Head _M_head_impl;
112     };
113 
114   template<std::size_t _Idx, typename... _Elements>
115     struct _Tuple_impl;
116 
117   template<std::size_t _Idx>
118     struct _Tuple_impl<_Idx>
119     {
120       template<std::size_t, typename...> friend class _Tuple_impl;
121 
122       _Tuple_impl() = default;
123     };
124 
125    template<typename... _Elements>
126    class tuple;
127 
128   template<std::size_t _Idx, typename _Head, typename... _Tail>
129     struct _Tuple_impl<_Idx, _Head, _Tail...>
130     : public _Tuple_impl<_Idx + 1, _Tail...>,
131       private _Head_base<_Idx, _Head, /*__empty_not_final<_Head>::value*/
132                          0>
133     {
134       template<std::size_t, typename...> friend class _Tuple_impl;
135 
136       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
137       typedef _Head_base<_Idx, _Head, /*__empty_not_final<_Head>::value*/ 0> _Base;
138 
139       static constexpr const _Head&
_M_headstd::_Tuple_impl140       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
141 
142       static constexpr const _Inherited&
_M_tailstd::_Tuple_impl143       _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
144 
145       template<typename _UHead, typename... _UTail, typename = false_type>
146         explicit
_Tuple_implstd::_Tuple_impl147         constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
148 	: _Inherited(std::forward<_UTail>(__tail)...),
149 	  _Base(std::forward<_UHead>(__head)) { }
150 
151       constexpr
_Tuple_implstd::_Tuple_impl152       _Tuple_impl(_Tuple_impl&& __in)
153       noexcept(false)
154       : _Inherited(std::move(_M_tail(__in))),
155 	_Base(std::forward<_Head>(_M_head(__in))) { }
156 
157     };
158 
159   /// Primary class template, tuple
160   template<typename... _Elements>
161     class tuple : public _Tuple_impl<0, _Elements...>
162     {
163       typedef _Tuple_impl<0, _Elements...> _Inherited;
164 
165     public:
166       template<typename... _UElements, typename = true_type>
167 	explicit
tuple(_UElements &&...__elements)168         constexpr tuple(_UElements&&... __elements)
169 	: _Inherited(std::forward<_UElements>(__elements)...) {	}
170     };
171 
172 
173   /// Gives the type of the ith element of a given tuple type.
174   template<std::size_t __i, typename _Tp>
175     struct tuple_element;
176 
177   /**
178    * Recursive case for tuple_element: strip off the first element in
179    * the tuple and retrieve the (i-1)th element of the remaining tuple.
180    */
181   template<std::size_t __i, typename _Head, typename... _Tail>
182     struct tuple_element<__i, tuple<_Head, _Tail...> >
183     : tuple_element<__i - 1, tuple<_Tail...> > { };
184 
185   /**
186    * Basis case for tuple_element: The first element is the one we're seeking.
187    */
188   template<typename _Head, typename... _Tail>
189     struct tuple_element<0, tuple<_Head, _Tail...> >
190     {
191       typedef _Head type;
192     };
193 
194   template<std::size_t __i, typename _Tp>
195     struct tuple_element<__i, const _Tp>
196     {
197       typedef const typename tuple_element<__i, _Tp>::type type;
198     };
199 
200 
201   template<std::size_t __i, typename _Head, typename... _Tail>
202     constexpr typename __add_c_ref<_Head>::type
__get_helper(const _Tuple_impl<__i,_Head,_Tail...> & __t)203     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
204     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
205 
206   // Return a reference (const reference, rvalue reference) to the ith element
207   // of a tuple.  Any const or non-const ref elements are returned with their
208   // original type.
209   template<std::size_t __i, typename... _Elements>
210     constexpr typename __add_c_ref<
211                       typename tuple_element<__i, tuple<_Elements...>>::type
212                     >::type
get(const tuple<_Elements...> & __t)213     get(const tuple<_Elements...>& __t) noexcept
214     { return __get_helper<__i>(__t); }
215 
216 
217   template<typename... _Elements>
218     tuple<_Elements&&...>
forward_as_tuple(_Elements &&...__args)219     forward_as_tuple(_Elements&&... __args) noexcept
220     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
221 
222 } // namespace std
223 
224 
225 using namespace std;
226 
227 template <class T>
tpl(T x)228 void tpl(T x) {
229   printf("tpl: &C=%p\n", get<0>(x).C);
230   printf("tpl:  C=%s\n", get<0>(x).C);
231 };
232 
233 template<typename... _Elements>
234     tuple<_Elements&&...>
my_forward_as_tuple(_Elements &&...__args)235 my_forward_as_tuple(_Elements&&... __args) noexcept
236 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
237 
238 
239 namespace {
call(const char * pass,STR && __k)240 void call(const char* pass, STR&& __k) {
241   printf("%s: &rval=%p\n", pass, &__k);
242   printf("%s: &C=%p\n", pass, __k.C);
243   tpl(my_forward_as_tuple(std::move(__k)));
244 }
245 }
246 
clang()247 void clang() {
248   call("clang", "a");
249 }
250