1/* { dg-do run } */
2/* { dg-options "-fstrict-aliasing" } */
3
4extern "C" void abort (void);
5namespace sigc {
6  template <class T_type>
7  struct type_trait
8  {
9    typedef T_type& pass;
10    typedef const T_type& take;
11    typedef T_type* pointer;
12  };
13  template <class T_base, class T_derived>
14  struct is_base_and_derived
15  {
16    struct big {
17      char memory[64];
18    };
19    static big is_base_class_(...);
20    static char is_base_class_(typename type_trait<T_base>::pointer);
21    static const bool value =
22    sizeof(is_base_class_(reinterpret_cast<typename type_trait<T_derived>::pointer>(0))) ==
23    sizeof(char);
24  };
25  struct nil;
26  struct functor_base {};
27  template <class T_functor, bool I_derives_functor_base=is_base_and_derived<functor_base,T_functor>::value>
28  struct functor_trait
29  {
30  };
31  template <class T_functor>
32  struct functor_trait<T_functor,true>
33  {
34    typedef typename T_functor::result_type result_type;
35    typedef T_functor functor_type;
36  };
37  template <class T_arg1, class T_return>
38  class pointer_functor1 : public functor_base
39  {
40    typedef T_return (*function_type)(T_arg1);
41    function_type func_ptr_;
42  public:
43    typedef T_return result_type;
44    explicit pointer_functor1(function_type _A_func): func_ptr_(_A_func) {}
45    T_return operator()(typename type_trait<T_arg1>::take _A_a1) const
46    { return func_ptr_(_A_a1); }
47  };
48  template <class T_arg1, class T_return>
49  inline pointer_functor1<T_arg1, T_return>
50  ptr_fun1(T_return (*_A_func)(T_arg1))
51  { return pointer_functor1<T_arg1, T_return>(_A_func); }
52  struct adaptor_base : public functor_base {};
53  template <class T_functor,
54    class T_arg1=void,
55    bool I_derives_adaptor_base=is_base_and_derived<adaptor_base,T_functor>::value>
56  struct deduce_result_type
57  { typedef typename functor_trait<T_functor>::result_type type; };
58  template <class T_functor>
59  struct adaptor_functor : public adaptor_base
60  {
61    template <class T_arg1=void>
62    struct deduce_result_type
63    { typedef typename sigc::deduce_result_type<T_functor, T_arg1>::type type; };
64    typedef typename functor_trait<T_functor>::result_type result_type;
65    result_type
66    operator()() const;
67    template <class T_arg1>
68    typename deduce_result_type<T_arg1>::type
69    operator()(T_arg1 _A_arg1) const
70    { return functor_(_A_arg1); }
71    explicit adaptor_functor(const T_functor& _A_functor)
72      : functor_(_A_functor)
73    {}
74    mutable T_functor functor_;
75  };
76  template <class T_functor>
77  typename adaptor_functor<T_functor>::result_type
78  adaptor_functor<T_functor>::operator()() const
79  { return functor_(); }
80  template <class T_functor, bool I_isadaptor = is_base_and_derived<adaptor_base, T_functor>::value> struct adaptor_trait;
81  template <class T_functor>
82  struct adaptor_trait<T_functor, true>
83  {
84    typedef T_functor adaptor_type;
85  };
86  template <class T_functor>
87  struct adaptor_trait<T_functor, false>
88  {
89    typedef typename functor_trait<T_functor>::functor_type functor_type;
90    typedef adaptor_functor<functor_type> adaptor_type;
91  };
92  template <class T_functor>
93  struct adapts : public adaptor_base
94  {
95    typedef typename adaptor_trait<T_functor>::adaptor_type adaptor_type;
96    explicit adapts(const T_functor& _A_functor)
97      : functor_(_A_functor)
98    {}
99    mutable adaptor_type functor_;
100  };
101  template <class T_type>
102  struct reference_wrapper
103  {
104  };
105  template <class T_type>
106  struct unwrap_reference
107  {
108    typedef T_type type;
109  };
110  template <class T_type>
111  class bound_argument
112  {
113  public:
114    bound_argument(const T_type& _A_argument)
115      : visited_(_A_argument)
116    {}
117    inline T_type& invoke()
118    { return visited_; }
119    T_type visited_;
120  };
121  template <class T_wrapped>
122  class bound_argument< reference_wrapper<T_wrapped> >
123  {
124  };
125  template <int I_location, class T_functor, class T_type1=nil>
126  struct bind_functor;
127  template <class T_functor, class T_type1>
128  struct bind_functor<-1, T_functor, T_type1> : public adapts<T_functor>
129  {
130    typedef typename adapts<T_functor>::adaptor_type adaptor_type;
131    typedef typename adaptor_type::result_type result_type;
132    result_type
133    operator()()
134    {
135      return this->functor_.template operator()<typename type_trait<typename unwrap_reference<T_type1>::type>::pass> (bound1_.invoke());
136    }
137    bind_functor(typename type_trait<T_functor>::take _A_func, typename type_trait<T_type1>::take _A_bound1)
138      : adapts<T_functor>(_A_func), bound1_(_A_bound1)
139    {}
140    bound_argument<T_type1> bound1_;
141  };
142  template <class T_type1, class T_functor>
143  inline bind_functor<-1, T_functor,
144		      T_type1>
145  bind(const T_functor& _A_func, T_type1 _A_b1)
146  { return bind_functor<-1, T_functor,
147      T_type1>
148      (_A_func, _A_b1);
149  }
150  namespace internal {
151    struct slot_rep;
152    typedef void* (*hook)(slot_rep *);
153    struct slot_rep
154    {
155      hook call_;
156    };
157  }
158  class slot_base : public functor_base
159  {
160  public:
161    typedef internal::slot_rep rep_type;
162    explicit slot_base(rep_type* rep)
163      : rep_(rep)
164    {
165    }
166    mutable rep_type *rep_;
167  };
168  namespace internal {
169    template <class T_functor>
170    struct typed_slot_rep : public slot_rep
171    {
172      typedef typename adaptor_trait<T_functor>::adaptor_type adaptor_type;
173      adaptor_type functor_;
174      inline typed_slot_rep(const T_functor& functor)
175	: functor_(functor)
176      {
177      }
178    };
179    template<class T_functor>
180    struct slot_call0
181    {
182      static void *call_it(slot_rep* rep)
183      {
184	typedef typed_slot_rep<T_functor> typed_slot;
185	typed_slot *typed_rep = static_cast<typed_slot*>(rep);
186	return (typed_rep->functor_)();
187      }
188      static hook address()
189      {
190	return &call_it;
191      }
192    };
193  }
194
195  class slot0 : public slot_base
196  {
197  public:
198    typedef void * (*call_type)(rep_type*);
199    inline void *operator()() const
200    {
201      return slot_base::rep_->call_ (slot_base::rep_);
202    }
203    template <class T_functor>
204    slot0(const T_functor& _A_func)
205      : slot_base(new internal::typed_slot_rep<T_functor>(_A_func))
206    {
207      slot_base::rep_->call_ = internal::slot_call0<T_functor>::address();
208    }
209  };
210}
211struct A
212{
213  static void *foo (void *p) { return p; }
214  typedef sigc::slot0 C;
215  C bar();
216};
217A::C A::bar ()
218{
219  return sigc::bind (sigc::ptr_fun1 (&A::foo), (void*)0);
220}
221int main (void)
222{
223  A a;
224  if (a.bar ()() != 0)
225    abort ();
226}
227