From: u90jl@ecs.ox.ac.UK
Subject: g++-2.3.2: Internal compiler error 123 using pointer-to-member typedef
Organization: GNUs Not Usenet
Distribution: gnu
Date: Tue, 15 Dec 1992 09:58:09 GMT

Sorry I don't have the time to shorten this code.  Here it is
preprocessed, anyway.  Search through the source for "bug" for a helpful
comment.

--> gcc -v -c -Wall bug.cc

gcc version 2.3.2
 /mclab/u90jl/gnu/lib/gcc-lib/sparc-sun-sunos4.1.1/2.3.2/cpp -lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__sparc -D__sun -D__unix -Wall bug.cc /usr/tmp/cca02621.i
GNU CPP version 2.3.2 (sparc)
 /mclab/u90jl/gnu/lib/gcc-lib/sparc-sun-sunos4.1.1/2.3.2/cc1plus /usr/tmp/cca02621.i -quiet -dumpbase bug.cc -Wall -version -o /usr/tmp/cca02621.s
GNU C++ version 2.3.2 (sparc) compiled by GNU C version 2.3.2.
bug.cc:179: Internal compiler error 123.
bug.cc:179: Please report this to `bug-g++@prep.ai.mit.edu'.

Jamie
--
typedef long _G_clock_t;
typedef short _G_dev_t;
typedef long   _G_fpos_t;
typedef unsigned short _G_gid_t;
typedef unsigned long _G_ino_t;
typedef unsigned short _G_mode_t;
typedef short _G_nlink_t;
typedef long _G_off_t;
typedef int _G_pid_t;
typedef int _G_ptrdiff_t;
typedef int _G_sigset_t;
typedef int _G_size_t;
typedef long _G_time_t;
typedef unsigned short _G_uid_t;
typedef unsigned short _G_wchar_t;
typedef int   _G_ssize_t;
typedef char * _G_va_list;
extern "C" {
extern	struct	_iobuf {
	int	_cnt;
	unsigned char *_ptr;
	unsigned char *_base;
	int	_bufsiz;
	short	_flag;
	char	_file;		 
} _iob[];
extern struct _iobuf 	*__hide_fopen ();
extern struct _iobuf 	*__hide_fdopen ();
extern struct _iobuf 	*__hide_freopen ();
extern struct _iobuf 	*__hide_popen ();
extern struct _iobuf 	*tmpfile();
extern long	__hide_ftell ();
extern char	*fgets();
extern char	*gets();
extern char	*__hide_sprintf ();
extern char	*ctermid();
extern char	*cuserid();
extern char	*__hide_tempnam ();
extern char	*tmpnam();
}
extern "C" {
int    fclose(struct _iobuf *);
struct _iobuf *  fdopen(int, const char*);
int    fflush(struct _iobuf *);
int    fgetc(struct _iobuf *);
char*  fgets(char*, int, struct _iobuf  *);
struct _iobuf *  fopen(const char*, const char*);
int    fprintf(struct _iobuf *, const char* ...);
int    fputc(int, struct _iobuf *);
int    fputs(const char*, struct _iobuf *);
_G_size_t  fread(void*, _G_size_t , _G_size_t , struct _iobuf *);
struct _iobuf *  freopen(const char*, const char*, struct _iobuf *);
int    fscanf(struct _iobuf *, const char* ...);
int    fseek(struct _iobuf *, long, int);
long   ftell(struct _iobuf  *);
_G_size_t  fwrite(const void*, _G_size_t , _G_size_t , struct _iobuf *);
char*  gets(char*);
int    getw(struct _iobuf *);
int    pclose(struct _iobuf *);
void   perror(const char*);
struct _iobuf *  popen(const char*, const char*);
int    printf(const char* ...);
int    puts(const char*);
int    putw(int, struct _iobuf *);
int    rewind(struct _iobuf *);
int    scanf(const char* ...);
void   setbuf(struct _iobuf *, char*);
void   setbuffer(struct _iobuf *, char*, int);
int    setlinebuf(struct _iobuf *);
int    setvbuf(struct _iobuf *, char*, int, _G_size_t );
int    sscanf(char*, const char* ...);
struct _iobuf *  tmpfile();
int    ungetc(int, struct _iobuf *);
int    vfprintf (...) ;
int    vprintf (...) ;
int  sprintf (...) ;
int  vsprintf (...) ;
extern int _filbuf (...) ;
extern int _flsbuf (...) ;
}
extern "C" {
extern "C" {
extern void __eprintf (const char *, const char *, unsigned, const char *);
}
}
extern "C" {
typedef int ptrdiff_t;
typedef int _G_size_t ;
typedef __wchar_t wchar_t;
}
class Object {
  private:
    class __Object_init {
      public:
	__Object_init();
    };
    static __Object_init init;
    class __Block_header {
	friend Object;
	__Block_header *tail;
    };
    static __Block_header *current_block;
    inline Object() {}
    static _G_size_t  block_size;
    static char *next_free, *block_end;
    friend class ObjectP_Object;
    static class ObjectP_Object *root_list;
    friend __Object_init;
    static char *new_block(_G_size_t );
    virtual Object *collect_yourself(void) { return 0; }
  public:
    inline void *operator new(_G_size_t  size)
    {
	char *result=next_free;
	return (Object *)(((next_free += size) > block_end)
			  ? new_block(size) : result);
    }
    inline void *operator new(_G_size_t , Object *where)
    {
	return where;
    }
    void operator delete(void *);
    static inline Object *__increment_and_check_for_overflow(_G_size_t  size)
    {
	char *result=next_free;
	return (Object *)((next_free += size) > block_end ? result : 0);
    }
    static inline Object *__allocate_slow(_G_size_t  size)
    {
	return (Object *)new_block(size);
    }
};
class ObjectP_Object {
    ObjectP_Object *tail;
  public:
    Object *p;
    inline ObjectP_Object()
      { tail=Object::root_list; Object::root_list=this; p=0; }
    inline ObjectP_Object(Object *object)
      { tail=Object::root_list; Object::root_list=this; p=object; }
    inline ~ObjectP_Object() { Object::root_list=tail; }
    inline operator Object * (void) { return p; }
    inline ObjectP_Object & operator = (Object *op) { p=op; return *this; }
    inline ObjectP_Object & operator = (ObjectP_Object &op)
      { p=op.p; return *this; }
};
template <class T> class ObjectP : public ObjectP_Object {
  public:
    inline ObjectP()
      : ObjectP_Object() {}
    inline ObjectP(T *object)
      : ObjectP_Object(object) {}
    inline ~ObjectP() {}
    inline operator T * (void) { return (T *)p; }
    inline ObjectP<T> & operator = (T *op) { p=op; return *this; }
    inline ObjectP<T> & operator = (ObjectP<T> &op) { p=op.p; return *this; }
};
class TreeCode : public Object;
class Bindings : public Object {
    friend class __dummy_friend;  
    class Binding_equivalence *equivalences_at_this_binding;
    Bindings *tail;
    static ObjectP<Bindings> stack;
    unsigned int binding_level;
    static unsigned int current_binding_level;
    static inline void pop_to(Bindings *);
    inline Bindings() {}
  public:
    Bindings *new_binding_group(void);
    void bind(class Binding_equivalence *, class TreeCode *);
    class TreeCode;

///////////////////////////////////////////////////////////////////////////////
// This is where the bug shows up...
// Uncomment the first typedef, comment out the second and it compiles fine.
///////////////////////////////////////////////////////////////////////////////

    // typedef int __PTM_TreeCodeP_type;
    typedef TreeCode *(TreeCode::*__PTM_TreeCodeP_type);
    void declare_reference(class Binding_equivalence *, class TreeCode *,
			   __PTM_TreeCodeP_type);
    static void terminate_all_groups(void);
};
class Binding_equivalence : public Object {
    friend class Bindings;
    class Binding_backpatch_stack *backpatch_stack;
    class Binding_value_stack *value_stack;
    Binding_equivalence *next_at_this_binding;
  public:
    inline Binding_equivalence()
      : backpatch_stack(0), value_stack(0), next_at_this_binding(0) {}
};
void bind_lhs_to_exp(class TreeCode *, class TreeCode *);
class Binding_backpatch : public Object {
    friend class Bindings;
    friend class Binding_backpatch_stack;
    Binding_backpatch *tail;
    class TreeCode *object, **patch_pointer;
    inline Binding_backpatch(Binding_backpatch *tl, class TreeCode *o,
			     class TreeCode **pp)
      : tail(tl), object(o), patch_pointer(pp) {}
};
class Binding_backpatch_stack : public Object {
    friend class Bindings;
    unsigned int binding_level;
    Binding_backpatch_stack *tail;
    Binding_backpatch backpatch_list_head;
    inline Binding_backpatch_stack(Binding_backpatch_stack *tl,
				   unsigned int level,
				   class TreeCode *o, class TreeCode **pp)
      : tail(tl), binding_level(level), backpatch_list_head(0, o, pp) {}
};
class Binding_value_stack : public Object {
    friend class Bindings;
    unsigned int binding_level;
    Binding_value_stack *tail;
    class TreeCode *value;
    class Binding_equivalence *saved_next_at_this_binding;
    inline Binding_value_stack(Binding_value_stack *tl,
			       unsigned int level,
			       class TreeCode *val,
			       class Binding_equivalence *saved_next)
      : tail(tl), binding_level(level), value(val),
        saved_next_at_this_binding(saved_next) {}
};
ObjectP<Bindings> Bindings::stack=0;
unsigned int Bindings::current_binding_level=0;
inline void Bindings::pop_to(Bindings *to)
{
    if (stack != to) {
	Bindings *bp=stack;
	((void) ((!to || to->binding_level < current_binding_level) ? 0 : (__eprintf ("%s:%u: failed assertion `%s'\n",	 "Bindings.cc",  91, "!to || to->binding_level < current_binding_level"), 0) )) ;
	unsigned int binding_level=current_binding_level;
	do {
	    Binding_equivalence *eqp=bp->equivalences_at_this_binding;
	    while (eqp) {
		Binding_value_stack *vsp=eqp->value_stack;
		if (vsp && vsp->binding_level == binding_level) {
		    eqp->value_stack=vsp->tail;
		    {
			Binding_backpatch_stack *bpsp=eqp->backpatch_stack;
			while (bpsp && bpsp->binding_level >= binding_level)
			    bpsp=bpsp->tail;
			eqp->backpatch_stack=bpsp;
		    }
		    Binding_equivalence *next_eqp=eqp->next_at_this_binding;
		    eqp->next_at_this_binding=vsp->saved_next_at_this_binding;
		    eqp=next_eqp;
		} else {
		    eqp=eqp->next_at_this_binding;
		}
	    }
	    bp=bp->tail;
	    binding_level--;
	} while (bp != to);
	stack=to;
	current_binding_level=binding_level;
    }
}
Bindings *Bindings::new_binding_group(void)
{
    pop_to(this);
    Bindings *result;
     result=( Bindings *)Object::__increment_and_check_for_overflow(sizeof( Bindings)); if (! result) {	ObjectP_Object __pp1(this);	 result=( Bindings *)Object::__allocate_slow(sizeof( Bindings));	this=(typeof(this))(__pp1.p);	}	 result=new( result)  Bindings  (); ;
    result->tail=this;
    stack=result;
    current_binding_level++;
    result->binding_level=current_binding_level;
    result->equivalences_at_this_binding=0;
    return result;
}
void Bindings::bind(Binding_equivalence *name, class TreeCode *value)
{
    pop_to(this);  
    {
	 
	Binding_backpatch_stack *bpsp=name->backpatch_stack;
	while (bpsp && bpsp->binding_level >= binding_level) {
	    Binding_backpatch *bpp=&bpsp->backpatch_list_head;
	    do {
		*(bpp->patch_pointer)=value;
		bpp=bpp->tail;
	    } while (bpp);
	    bpsp=bpsp->tail;
	}
	name->backpatch_stack=bpsp;
    }
    {
	Binding_value_stack *bvsp=name->value_stack;
	if (bvsp) {
	    if (bvsp->binding_level == binding_level) {
		printf("A value just got re-bound!\n");
		return;
	    }
	    if (bvsp->value == value)
		return;
	}
	 bvsp=( Binding_value_stack *)Object::__increment_and_check_for_overflow(sizeof( Binding_value_stack)); if (! bvsp) {	ObjectP<Object> __pp1(this), __pp2( name), __pp3( value);	 bvsp=( Binding_value_stack *)Object::__allocate_slow(sizeof( Binding_value_stack));	this=(typeof(this))(__pp1.p);	 name=(typeof( name))(__pp2.p);	 value=(typeof( value))(__pp3.p);	}	 bvsp=new( bvsp)  Binding_value_stack 
		       (name->value_stack, binding_level,
			value, name->next_at_this_binding); ;
	name->value_stack=bvsp;
	name->next_at_this_binding=equivalences_at_this_binding;
	equivalences_at_this_binding=name;
    }
}
void
Bindings::declare_reference(Binding_equivalence *name,
			    class TreeCode *object,
			    __PTM_TreeCodeP_type patch_pointer)
{
    pop_to(this);
    {
	Binding_value_stack *bvsp=name->value_stack;
	if (bvsp) {
	    // object->*patch_pointer=bvsp->value;
	    if (bvsp->binding_level == binding_level) {
		 
		 
		return;
	    }
	     
	     
	     
	} else {
	     
	    // object->*patch_pointer=0;
	}
    }
    Binding_backpatch_stack *bpsp=name->backpatch_stack;
    if (bpsp) {
	if (bpsp->binding_level != binding_level) {
	    if (bpsp->binding_level < binding_level) {
		
			       bpsp=( Binding_backpatch_stack *)Object::__increment_and_check_for_overflow(sizeof( Binding_backpatch_stack)); if (!			       bpsp) {	ObjectP<Object> __pp1(this), __pp2( name), __pp3( object);				       bpsp=( Binding_backpatch_stack *)Object::__allocate_slow(sizeof( Binding_backpatch_stack));	this=(typeof(this))(__pp1.p);	 name=(typeof( name))(__pp2.p);	 object=(typeof( object))(__pp3.p);	}				       bpsp=new(			       bpsp)  Binding_backpatch_stack 
			       (name->backpatch_stack, binding_level,
				object, 0); ;
		name->backpatch_stack=bpsp;
		return;
	    }
	    Binding_backpatch_stack *lower_bpsp;
	    while ((lower_bpsp=bpsp->tail)
		   && lower_bpsp->binding_level >= binding_level) {
		 
		bpsp=lower_bpsp;
	    }
	    bpsp->binding_level=binding_level;
	    name->backpatch_stack=bpsp;
	}
	Binding_backpatch *bpp;
	
		       bpp=( Binding_backpatch *)Object::__increment_and_check_for_overflow(sizeof( Binding_backpatch)); if (!		       bpp) {	ObjectP_Object __pp1(object), __pp2( bpsp);			       bpp=( Binding_backpatch *)Object::__allocate_slow(sizeof( Binding_backpatch));	object=(typeof(object))(__pp1.p);	 bpsp=(typeof( bpsp))(__pp2.p);	}			       bpp=new(		       bpp)  Binding_backpatch 
		       (bpsp->backpatch_list_head.tail,
			object, 0); ;
	bpsp->backpatch_list_head.tail=bpp;
	return;
    }
		   bpsp=( Binding_backpatch_stack *)Object::__increment_and_check_for_overflow(sizeof( Binding_backpatch_stack)); if (!		   bpsp) {	ObjectP<Object> __pp1(this), __pp2( name), __pp3( object);			   bpsp=( Binding_backpatch_stack *)Object::__allocate_slow(sizeof( Binding_backpatch_stack));	this=(typeof(this))(__pp1.p);	 name=(typeof( name))(__pp2.p);	 object=(typeof( object))(__pp3.p);	}			   bpsp=new(		   bpsp)  Binding_backpatch_stack 
		   (0, binding_level, object, 0); ;
    name->backpatch_stack=bpsp;
    return;
}
void Bindings::terminate_all_groups(void)
{
    pop_to(0);
}
void bind_lhs_to_exp(TreeCode *lhs, TreeCode *expression)
{
    printf("A binding just happend.  Don't know what binding.  ;-)\n");
}