[gnu.g++.bug] g++1.36.0

Briggs.pa@XEROX.COM (09/18/89)

In gcc 1.35.98, the code generated by genextract for insn-extract.c aborts
on illegal insns with a call to abort().

In gcc 1.35.99 this has been replaced by a call to
fatal_insn_not_found(insn), a function which is now provided in gcc's
toplev.c

If you attempt to build a g++ based on gcc-1.35.99 (using the genextract
from that release) cc1plus fails to load because the function
fatal_insn_not_found is not provided by the g++ toplev.c.

I believe diffs for an appropriate patch to g++'s toplev.c would be:

*** toplev.c.orig	Thu Sep  7 09:29:29 1989
--- toplev.c	Sun Sep 17 22:58:13 1989
***************
*** 475,480 ****
--- 475,488 ----
    error (s, v);
    exit (34);
  }
+ void
+ fatal_insn_not_found (insn)
+      rtx insn;
+ {
+   error ("The followin insn was not recognizable:" , 0);
+   debug_rtx (insn);
+   abort ();
+ }
  
  static int need_error_newline;
  

dwf%hope@lanl.gov (David W. Forslund) (10/17/89)

G++1.36.0 fails to compile the following code on a Sun3 running
OS4.0.3.  It compiles fine on a Sun4 running OS4.0.3.

bank1.C:
--------------------
// Main bank simulation program
// This program simulates a bank with one waiting line
// and n servers.  When one or more servers is free,
// the server is chosen randomly
// File bank1.c

#include "queue.h"
#include "server.h"
extern random2(int,int);
extern "C" double drand48();


float average_iat;		// Average interarraival time
float simulation_time;		// Time, in minutes, bank is open
int number_servers;		// Number of servers in system
float *average_service_time;	// Array of av_serv_times
float arrival_time;

//Object declarations
customer_queue q;
time t;
server *s;  //Array of servers

void get_input()
{
  printf("\nEnter the number of servers:");
  scanf("%d",&number_servers);

  average_service_time = new float[number_servers];
  s = new server[number_servers];

  for (int z=0 ; z<number_servers ; z++)
  {
    printf("\nEnter average service time for server %d:", z+1);
    scanf("%f",&average_service_time[z]);
    s[z].set_av_service_time(average_service_time[z]);
  }
  printf("\nEnter the average interarrival time:");
  scanf("%f",&average_iat);
  printf("\nNumber of minutes for the simulation:");
  scanf("%f",&simulation_time);
  printf("\n");
}
main()
{
  extern int get_next_event(float &n_event_time);
  extern int server_avail(int &n);
  extern void report_stats(customer_queue q);
  extern void title();
  extern float generate_iat(time t);

  float next_event_time;
  int next_event;
  int server_no;

  get_input();
  title();
  printf("Simulating...\n");
  arrival_time= generate_iat(t);
  do
  {
    //During business hours...
    //Determine the next event
    next_event = get_next_event(next_event_time);
#ifdef debug
      printf("\nThe next event = %d",next_event);
      printf("next_event_time|%f",next_event_time);
#endif
    if(next_event_time <= simulation_time)
    {
      t.set_time(next_event_time);
      if(next_event > 0 && q.size() > 0)
      {  //Take a customer from the queue
	 q.remove(t);
	 s[next_event -1].serve_cust(t);
#ifdef debug
	   printf("\nThe queue size = %d\n\n",q.size());
#endif
      }
      else if (next_event> 0 && q.size() == 0)
      {
	s[next_event -1].set_server_free();
#ifdef debug
	  printf("\nThe queue size = %d\n\n",q.size();
#endif
      }
      else //Next event is a customer arrival
      {
	if (q.size() == 0 && server_avail(server_no))
	{  // Customer goes directly to server server_no
	  q.insert(t);
	  q.remove(t);  // Insert and remove to update stats
	  s[server_no].serve_cust(t);
#ifdef debug
	    printf("\nThe queue size = %d\n\n",q.size());
#endif
        }
	else //customer joins queue
	{
	  q.insert(t);
#ifdef debug
	    printf("\nThe queue size = %d\n\n",q.size());
#endif
        }
      arrival_time = generate_iat(t);
      }
    }
  } while (next_event_time <= simulation_time);
  arrival_time = large;  //Bank is now closed
  next_event = get_next_event(next_event_time);
#ifdef debug
    printf("\nBank closed\n");
    printf("\nThe next_event = %d", next_event);
    printf("\nnext_event_time = %f",next_event_time);
    printf("\nCurrent queue size = %d",q.size());
#endif
  // Determine wither all servers are free
  while (next_event !=0)
  {
    t.set_time(next_event_time);
    if (q.size() > 0)
    {
      q.remove(t);
      s[next_event -1].serve_cust(t);
    }
    else
     s[next_event-1].set_server_free();
    next_event = get_next_event(next_event_time);
  }
  report_stats(q);
}
float generate_iat(time t)
{  //Exponential distribution with mean given by av_
   // interarrival_time
   return(-average_iat *log(rand_real() ) + t.get_time());
}

int get_next_event(float&n_event_time)
{
  float min = arrival_time;
  int choice = 0;
  float temp;

  for (int i=1;i<=number_servers; i++)
  {
    if (( temp=s[i-1].get_next_available())<min)
    {
      choice =i;
      min =temp;
    }
  }
  n_event_time = min;
  return choice;
}

int server_avail(int &n)
{
  // Returns 0 if no server is available
  // otherwise returns 1 and number of available server
  int choice[30];
  int number_free = 0;

  for (int i = 0; i<number_servers;i++)
  {
    if (!s[i].busy())
    {
      choice[number_free] = i;
      number_free++;
    }
  }
  if (number_free == 0 )
    return 0;
  else
  {
    // Choose a random server among available servers
    n = choice[random2(0,number_free-1)];
    return 1;
  }
}

void report_stats(customer_queue q)
{
  printf("\nOutput Statistics");
  printf("\n--------------------");
  printf("\n\nAverage queue size	:%-8.3f",
	q.average_queue_size(t));
  printf("\n\nAverage queue wait time	:%-8.3f",
	q.average_queue_wait_time());
  printf("\n\nMaximum queue size	:%-d",q.maximum_queue_size());
  printf("\n\nTotal customers	:%-d",q.total_customers());
  for (int i = 0; i<number_servers;i++)
  {
    printf("\n\nServer %d service time: %-8.3f%c",
       i+1,s[i].fraction_of_time_service(t) *100,37);
    printf("\n\nServer %d total served: %-d\n",i+1,s[i].get_total_served());
  }
}

void title()
{
   printf("Discrete Event Simulation of Bank Queue");
   printf("\n-------------------------------------------\n");
}


int random2(int first,int number)
{
  return(first + (int) (drand48()*number));
}

queue.h:
----------------------
// Interface to dynamic queue class
// This queue is derived from a generic list class
// There is no limitation on the queue size except the size
//   of the heap
// file queue.h

#include "list.h"
#include "time.h"
#include "cust.h"

class queue: slist
// A private derived class to serve only class customer_queue
{
  friend class customer_queue;
  // The operations of put and get are accessible only
  // by the friend class customer queue.

  private:
    void put(customer *c) {slist::append((char*)c);}
    customer *get() {return (customer *)slist::get();}
  public:
    queue(): (sizeof(customer)){}

};
class customer_queue
{
  private:
    queue q; // A private queue derived from a generic list
    float last_event_time; //Time of last customer
			   // arrival or departure
    int cum_customers;	// Cumulative number of customers
    int current_queue_size;
    int peak_queue;
    float cum_queue_size_time;  // cumulative sum of products
				// of size of queue x time
    float cum_wait_time;	// Cumulative wait time for
				// all patrons
  public:
    void insert(time t);
    void remove(time t);
    customer_queue();
    int total_customers(){return cum_customers;}
    float average_queue_size(time t)
    {
      return (cum_queue_size_time / t.get_time());
    }
    int size() {return current_queue_size;}
    int maximum_queue_size() { return peak_queue;}
    float average_queue_wait_time()
    {
      return (cum_wait_time / cum_customers);
    }
    float total_wait_time() { return cum_wait_time;}
};

list.h:
----------------------------------
// This code defines a class for a singly linked list.
// File list.h

#include <stdio.h>
class node
{
   friend class slist;

   private:
	 node* next;
	 char* contents; // contents dynamically allocated
 };
 class slist
 {
    private:
	 node* head;  	// Head of list
	 int size;	// Number of bytes for contents
    public:
	 slist(int s) { head=0; size=s;}
	 void insert(char* a); 	// Add to the head of the list.
	 void append(char *a); 	// Add to the tail of the list.
	 char *get();		// Remove the head of the list.
	 void clear();		// Remove all the nodes in list.
	 ~slist(){ clear();}
 };

cust.h:
---------------------------------
 // Interface to clas customer
 //File cust.h

 class customer
 {
   friend class customer_queue;
   private:
     float arrival_time; // time when customer joins line
 };
time.h:
------------------------------
// Interace to class time
// File ltime.h

class time
{
  private:
    float current_time;
  public:
    time()
    {
     current_time=0.0;
    }
    float get_time() { return current_time;}
    void set_time(float t) {current_time = t;}
};
server.h:
------------------------------------
// Interface for class server
// File server.h

#include <stdio.h>
#include <math.h>

const float large = 999999.9;
extern float rand_real();
extern "C" double drand48();

class server
{
  private:
    int available;		// 1 if server is free, otherwise 0
    float cum_service_time;	// Cumulative service time
    float next_available;	// time when server is free
    int total_customers_served;
    float av_service_time;
  public:
    server()
    {
      cum_service_time = 0.0;
      total_customers_served = 0;
      next_available = large;
      available = 1;
    }

    void add_to_total_served() { total_customers_served++;}

    void set_server_free()
    {
      available = 1;
      next_available = large;
    }
    void set_server_busy() { available = 0;}

    int busy()
    {
      if(available)
	return 0;
      else
	return 1;
    }
    int get_total_served() {return total_customers_served;}

    void add_to_service_time (float t)
    { 
      cum_service_time += t; 
    }
    float fraction_of_time_service(time t)
    {
      return(cum_service_time/ (t.get_time()));
    }
    void set_next_available(float t) {next_available = t;}

    float get_next_available() {return next_available;}

    void serve_cust(time t)
    {
      float r = -av_service_time * log(rand_real());
      set_next_available(t.get_time() + r);
      add_to_service_time(r);
      add_to_total_served();
      set_server_busy();
    }

    void set_av_service_time(float average_service_time)
    {
      av_service_time = average_service_time;
    }
};
float rand_real()
{
	return(drand48());
}


This code, of course, is from Wiener and Pinson's book.



Script started on Mon Oct 16 15:13:07 1989
gcc -v -c -satchmo% g bank1.C
gcc version 1.36
gcc: bank1.C: linker input file unused since linking not done
satchmo% g++ -v -c -g bank1.C
gcc version 1.36.0- (based on GCC 1.36)
 /usr/local/lib/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -D__HAVE_68881__ -Dmc68020 bank1.C /usr/tmp/cca29787.cpp
GNU CPP version 1.36
 /usr/local/lib/gcc-cc1plus /usr/tmp/cca29787.cpp -quiet -dumpbase bank1.C -g -version -o /usr/tmp/cca29787.s
GNU C++ version 1.36.0- (based on GCC 1.36) (68k, MIT syntax) compiled by GNU C version 1.36.
default target switches: -m68020 -mc68020 -m68881 -mbitfield
In file included from /usr/local/lib/g++-include/errno.h:12, from /usr/local/lib/g++-include/math-68881.h:23, from /usr/local/lib/g++-include/math.h:33, from server.h:6, from bank1.C:8:
/usr/local/lib/g++-include/std.h:198: warning: type declaration of time shadowed
In file included from bank1.C:8:
server.h:50: parse error before `t'
server.h:58: parse error before `t'
server.h: In method float server::fraction_of_time_service (...):
server.h:52: `t' undeclared (first use this function)
server.h:52: (Each undeclared identifier is reported only once
server.h:52: for each function it appears in.)
server.h:51: warning: varargs function cannot be inline
server.h: In method void server::serve_cust (...):
server.h:61: `t' undeclared (first use this function)
server.h:59: warning: varargs function cannot be inline
bank1.C: At top level:
bank1.C:21: parse error before `t'
bank1.C:21: `t' used prior to declaration
bank1.C:21: warning: data definition lacks type or storage class
bank1.C: In function int main ():
bank1.C:50: parse error before `t'
bank1.C:71: object in '.' expression is not of aggregate type
bank1.C:74: bad argument 0 for function `customer_queue::remove (class time)' (type was int )
bank1.C:91: bad argument 0 for function `customer_queue::insert (class time)' (type was int )
bank1.C:92: bad argument 0 for function `customer_queue::remove (class time)' (type was int )
bank1.C:100: bad argument 0 for function `customer_queue::insert (class time)' (type was int )
bank1.C:120: object in '.' expression is not of aggregate type
bank1.C:123: bad argument 0 for function `customer_queue::remove (class time)' (type was int )
bank1.C: At top level:
bank1.C:132: parse error before `t'
bank1.C: In function float generate_iat (...):
bank1.C:135: object in '.' expression is not of aggregate type
bank1.C: In function void report_stats (class customer_queue):
bank1.C:186: bad argument 0 for function `customer_queue::average_queue_size (class time)' (type was int )

Note that it does compile with Cfront 2.0 (as well as g++ 1.36.0- on Sparc)
satchmo% CC -g -c bank1.C
CC  +g bank1.C:
"./queue.h", line 13: warning:  base slist private by default: please be explicit ``: private slist
cc   -c -I/usr/local/CC/sun3/incl  -g bank1.c
satchmo% ^D
script done on Mon Oct 16 15:13:46 1989

David Forslund
MS E531
Los Alamos National Laboratory
Los Alamos, NM 87545

(505) 665-1907
(dwf@lanl.gov)