Your weekly "Internal Compiler Error" report

Carlo Wood carlo@runaway.xs4all.nl
Fri Nov 6 08:56:00 GMT 1998


I ran into another ICE with egcs-1.1b.

>g++ -c bug.cc
bug.cc: In method `void event_server_tct<timer_event_request_ct,timer_priority_queue_tct>::request<alarm_tst_app_ct, busy_interface_ct>(class alarm_tst_app_ct &, void (alarm_tst_app_ct::*)(const class timer_event_type_ct &), struct timeval, class busy_interface_ct &)':
bug.cc:307:   instantiated from here
bug.cc:176: Internal compiler error.
bug.cc:176: Please submit a full bug report to `egcs-bugs@cygnus.com'.

I hate it to strip down my program every time (otherwise it would be a megabyte),
so I hope someone is actually looking into these reports :).  I'd appreciate
some feedback (just saying its looked into is ok).

-- 
 Carlo Wood  <carlo@runaway.xs4all.nl>

============The next line is the first line of the file 'bug.cc'============
#include <queue>
#include <list>

struct timeval {
  long tv_sec;
  long tv_usec;
};

class queued_event_bct;
template<class EVENTTYPE> class event_request_btct;
template<class EVENTTYPE, class EVENTREQUESTBASE> class queued_event_tct;

class busy_interface_ct {
private:
  unsigned int busy_depth;
  list<queued_event_bct *> events;
private:
  void flush_events(void);
public:
  busy_interface_ct(void) : busy_depth(0) { }
  bool is_busy(void) const { return (busy_depth > 0); }
  inline void set_busy(void) { ++busy_depth; }
  inline void unset_busy(void);
  template<class EVENTTYPE, class EVENTREQUESTBASE>
  inline void queue(EVENTREQUESTBASE *event_request, const EVENTTYPE &event_type);
  class never_busy_interface_ct {
  public:
    bool is_busy(void) { return false; }
    void set_busy(void) { }
    void unset_busy(void) { }
    template<class EVENTTYPE, class EVENTREQUESTBASE>
    void queue(EVENTREQUESTBASE *, const EVENTTYPE &) { }
  };
  static never_busy_interface_ct none;
};

template<class EVENTTYPE>
class event_request_btct {
  typedef EVENTTYPE event_type_ct;
  typedef void event_request_data_ct;
private:
  unsigned int reference_count;
public:
  virtual void handle(const EVENTTYPE &event_type) = 0;
  virtual void rehandle(const EVENTTYPE &event_type) = 0;
public:
  event_request_btct(void) : reference_count(1) {}
  void add_reference(void) { ++reference_count; }
  void release(void) { if (!--reference_count) delete this; }
protected:
  virtual ~event_request_btct() { }
};

class queued_event_bct {
protected:
  friend void busy_interface_ct::flush_events(void);
  virtual void retrigger(void) = 0;
};

template<class EVENTTYPE, class EVENTREQUESTBASE>
class queued_event_tct : public queued_event_bct {
private:
  EVENTREQUESTBASE *event_request;
  const EVENTTYPE &event_type;
private:
  friend class busy_interface_ct;
  queued_event_tct(EVENTREQUESTBASE *er, const EVENTTYPE &et) : event_request(er), event_type(et) { }
private:
  virtual void retrigger(void) { event_request->rehandle(event_type); delete this; }
};

inline void busy_interface_ct::unset_busy(void)
{
  if (busy_depth == 1 && !events.empty())
    flush_events();
  --busy_depth;
}

template<class EVENTTYPE, class EVENTREQUESTBASE>
inline void busy_interface_ct::queue(EVENTREQUESTBASE *event_request, const EVENTTYPE &event_type)
{
  events.push_back(new queued_event_tct<EVENTTYPE, EVENTREQUESTBASE>(event_request, event_type));
}

template<class EVENTREQUESTBASE, template<class EVENTREQUESTBASEPTR> class REQUESTQUEUE = deque>
class event_server_tct {
  typedef typename EVENTREQUESTBASE::event_type_ct EVENTTYPE;
  typedef REQUESTQUEUE<EVENTREQUESTBASE *> request_list_ct;

private:
  template<class EVENTCLIENT, class BUSYINTERFACE>
  class event_request_tct : public EVENTREQUESTBASE {
    EVENTCLIENT &event_client;
    void (EVENTCLIENT::*callbackfunc)(const EVENTTYPE &);
    BUSYINTERFACE &busy_interface;
  public:
    event_request_tct(EVENTCLIENT &ec, void (EVENTCLIENT::*em)(const EVENTTYPE &), BUSYINTERFACE &bi)
        : event_client(ec), callbackfunc(em), busy_interface(bi) { }
    virtual void handle(const EVENTTYPE &et);
    virtual void rehandle(const EVENTTYPE &et);
  };

  template<class EVENTCLIENT, class BUSYINTERFACE, class REQUESTCOOKIE>
  class event_request_cookie_tct : public EVENTREQUESTBASE {
    EVENTCLIENT &event_client;
    void (EVENTCLIENT::*callbackfunc)(const EVENTTYPE &, REQUESTCOOKIE);
    REQUESTCOOKIE cookie;
    BUSYINTERFACE &busy_interface;
  public:
    event_request_cookie_tct(EVENTCLIENT &ec, void (EVENTCLIENT::*em)(const EVENTTYPE &, REQUESTCOOKIE), REQUESTCOOKIE co, BUSYINTERFACE &bi)
        : event_client(ec), callbackfunc(em), cookie(co), busy_interface(bi) { }
    virtual void handle(const EVENTTYPE &et);
    virtual void rehandle(const EVENTTYPE &et);
  };

  template<class EVENTCLIENT, class BUSYINTERFACE>
  class event_request_data_tct : public EVENTREQUESTBASE {
    EVENTCLIENT &event_client;
    void (EVENTCLIENT::*callbackfunc)(const EVENTTYPE &);
    BUSYINTERFACE &busy_interface;
  public:
    template<class EVENTREQUESTDATA>
    event_request_data_tct(EVENTCLIENT &ec, void (EVENTCLIENT::*em)(const EVENTTYPE &), EVENTREQUESTDATA rd, BUSYINTERFACE &bi)
        : EVENTREQUESTBASE(rd), event_client(ec), callbackfunc(em), busy_interface(bi) { }
    virtual void handle(const EVENTTYPE &et);
    virtual void rehandle(const EVENTTYPE &et);
  };

  template<class EVENTCLIENT, class BUSYINTERFACE, class REQUESTCOOKIE>
  class event_request_data_cookie_tct : public EVENTREQUESTBASE {
    EVENTCLIENT &event_client;
    void (EVENTCLIENT::*callbackfunc)(const EVENTTYPE &, REQUESTCOOKIE);
    REQUESTCOOKIE cookie;
    BUSYINTERFACE &busy_interface;

  public:
    template<class EVENTREQUESTDATA>
    event_request_data_cookie_tct(EVENTCLIENT &ec, void (EVENTCLIENT::*em)(const EVENTTYPE &, REQUESTCOOKIE), EVENTREQUESTDATA  rd, REQUESTCOOKIE co, BUSYINTERFACE &bi)
        : EVENTREQUESTBASE(rd), event_client(ec), callbackfunc(em), cookie(co), busy_interface(bi) { }
    virtual void handle(const EVENTTYPE &et);
    virtual void rehandle(const EVENTTYPE &et);
  };

protected:
  request_list_ct requests;

public:
  ~event_server_tct();

public:
  template<class EVENTCLIENT>
  void request(EVENTCLIENT &ec, void (EVENTCLIENT::*em)(const EVENTTYPE &))
      { requests.push_back(new event_request_tct<EVENTCLIENT, busy_interface_ct::never_busy_interface_ct>(ec, em, busy_interface_ct::none)); }

  template<class EVENTCLIENT, class BUSYINTERFACE>
  void request(EVENTCLIENT &ec, void (EVENTCLIENT::*em)(const EVENTTYPE &), BUSYINTERFACE &bi)
      { requests.push_back(new event_request_tct<EVENTCLIENT, BUSYINTERFACE>(ec, em, bi)); }

  template<class EVENTCLIENT, class REQUESTCOOKIE>
  void request(EVENTCLIENT &ec, void (EVENTCLIENT::*em)(const EVENTTYPE &, REQUESTCOOKIE), REQUESTCOOKIE cookie)
      { requests.push_back(new event_request_cookie_tct<EVENTCLIENT, busy_interface_ct::never_busy_interface_ct, REQUESTCOOKIE>(ec, em, cookie, busy_interface_ct::none)); }

  template<class EVENTCLIENT, class REQUESTCOOKIE, class BUSYINTERFACE>
  void request(EVENTCLIENT &ec, void (EVENTCLIENT::*em)(const EVENTTYPE &, REQUESTCOOKIE),
      REQUESTCOOKIE cookie, BUSYINTERFACE &bi)
      { requests.push_back(new event_request_cookie_tct<EVENTCLIENT, BUSYINTERFACE, REQUESTCOOKIE>(ec, em, cookie, bi)); }

  template<class EVENTCLIENT>
  void request(EVENTCLIENT &ec, void (EVENTCLIENT::*em)(const EVENTTYPE &),
      typename EVENTREQUESTBASE::event_request_data_ct rd)
      { requests.push_back(new event_request_data_tct<EVENTCLIENT, busy_interface_ct::never_busy_interface_ct>(ec, em, rd, busy_interface_ct::none)); }

  template<class EVENTCLIENT, class BUSYINTERFACE>
  void request(EVENTCLIENT &ec, void (EVENTCLIENT::*em)(const EVENTTYPE &),
      typename EVENTREQUESTBASE::event_request_data_ct rd, BUSYINTERFACE &bi)
      { requests.push_back(new event_request_data_tct<EVENTCLIENT, BUSYINTERFACE>(ec, em, rd, bi)); }

  template<class EVENTCLIENT, class REQUESTCOOKIE>
  void request(EVENTCLIENT &ec, void (EVENTCLIENT::*em)(const EVENTTYPE &, REQUESTCOOKIE),
      typename EVENTREQUESTBASE::event_request_data_ct rd, REQUESTCOOKIE cookie)
      { requests.push_back(new event_request_data_cookie_tct<EVENTCLIENT, busy_interface_ct::never_busy_interface_ct, REQUESTCOOKIE>(ec, em, rd, cookie, busy_interface_ct::none)); }

  template<class EVENTCLIENT, class REQUESTCOOKIE, class BUSYINTERFACE>
  void request(EVENTCLIENT &ec, void (EVENTCLIENT::*em)(const EVENTTYPE &, REQUESTCOOKIE),
      typename EVENTREQUESTBASE::event_request_data_ct rd, REQUESTCOOKIE cookie, BUSYINTERFACE &bi)
      { requests.push_back(new event_request_data_cookie_tct<EVENTCLIENT, BUSYINTERFACE, REQUESTCOOKIE>(ec, em, rd, cookie, bi)); }
};

template<class EVENTREQUESTBASE, template<class EVENTREQUESTBASEPTR> class REQUESTQUEUE>
event_server_tct<EVENTREQUESTBASE, REQUESTQUEUE>::~event_server_tct()
{
  for (typename request_list_ct::iterator i = requests.begin(); i != requests.end(); ++i)
    (*i)->release();
}

template<class EVENTREQUESTBASE, template<class EVENTREQUESTBASEPTR> class REQUESTQUEUE>
template<class EVENTCLIENT, class BUSYINTERFACE>
void event_server_tct<EVENTREQUESTBASE, REQUESTQUEUE>::event_request_tct::handle(const EVENTTYPE &et)
{
  if (busy_interface.is_busy())
  {
    busy_interface.queue(static_cast<EVENTREQUESTBASE *>(this), et);
    add_reference();
  }
  else
  {
    busy_interface.set_busy();
    (event_client.*callbackfunc)(et);
    busy_interface.unset_busy();
  }
}

template<class EVENTREQUESTBASE, template<class EVENTREQUESTBASEPTR> class REQUESTQUEUE>
template<class EVENTCLIENT, class BUSYINTERFACE>
void event_server_tct<EVENTREQUESTBASE, REQUESTQUEUE>::event_request_tct::rehandle(const EVENTTYPE &et)
{
  (event_client.*callbackfunc)(et);
  release();
}

template<class EVENTREQUESTBASE, template<class EVENTREQUESTBASEPTR> class REQUESTQUEUE>
template<class EVENTCLIENT, class BUSYINTERFACE, class REQUESTCOOKIE>
void event_server_tct<EVENTREQUESTBASE, REQUESTQUEUE>::event_request_cookie_tct::handle(const EVENTTYPE &et)
{
  if (busy_interface.is_busy())
  {
    busy_interface.queue(static_cast<EVENTREQUESTBASE *>(this), et);
    add_reference();
  }
  else
  {
    busy_interface.set_busy();
    (event_client.*callbackfunc)(et, cookie);
    busy_interface.unset_busy();
  }
}

template<class EVENTREQUESTBASE, template<class EVENTREQUESTBASEPTR> class REQUESTQUEUE>
template<class EVENTCLIENT, class BUSYINTERFACE, class REQUESTCOOKIE>
void event_server_tct<EVENTREQUESTBASE, REQUESTQUEUE>::event_request_cookie_tct::rehandle(const EVENTTYPE &et)
{
  (event_client.*callbackfunc)(et, cookie);
  release();
}

class timer_event_data_ct {
private:
  struct timeval tv;
public:
  timer_event_data_ct(struct timeval tv_lp) : tv(tv_lp) {}
  struct timeval get_expire_time(void) { return tv; }
};

class timer_event_type_ct : public timer_event_data_ct {
public:
  timer_event_type_ct(struct timeval tv) : timer_event_data_ct(tv) { }
};

class timer_event_request_ct : public event_request_btct<timer_event_type_ct> {
  typedef struct timeval event_request_data_ct;	// Used to initialize this object (see constructor).
private:
  struct timeval expire_time;
public:
  event_request_data_ct get_expire_time(void) const { return expire_time; }
public:
  timer_event_request_ct(event_request_data_ct timeout) { }
public:
  friend inline bool operator<(timer_event_request_ct t1, timer_event_request_ct t2)
      {
	return t1.expire_time.tv_sec < t2.expire_time.tv_sec ||
	    (t1.expire_time.tv_sec == t2.expire_time.tv_sec &&
	    t1.expire_time.tv_usec < t2.expire_time.tv_usec);
      }
};

template<class T>
class timer_priority_queue_tct : public priority_queue<T, deque<T> > {
public:
  typedef deque<T>::iterator iterator;
  void push_back(T er) { push(er); }
  iterator begin() { return c.begin(); }
  iterator end() { return c.end(); }
};

class timer_event_server_ct : public event_server_tct<timer_event_request_ct, timer_priority_queue_tct> {
public:
  static timer_event_server_ct timer_server;
  struct timeval *handle_timeout(void);
};

template<class clientT, class event_methodT>
inline void set_alarm(clientT client_lp, event_methodT eventmethod_lp, struct timeval timeout_lp)
{
  timer_event_server_ct::timer_server.request(client_lp, eventmethod_lp, timeout_lp);
}

class alarm_tst_app_ct {
public:
  busy_interface_ct bi;
  void its_time(const timer_event_type_ct &) {}
};

int main(void)
{
  alarm_tst_app_ct obj;
  struct timeval timeout = { 2, 0 };
  timer_event_server_ct::timer_server.request(obj, &alarm_tst_app_ct::its_time, timeout, obj.bi);
}

void alarm_tst_app_ct::its_time(const timer_event_type_ct &expired_at)
{
  struct timeval timeout = { 4, 0 };
  timer_event_server_ct::timer_server.request(*this, &its_time, timeout, bi);
}



More information about the Gcc-bugs mailing list