[gnu.g++.bug] BUG: segmentation fault in cplus-parse.y

jj@idris.id.dk (Jesper Joergensen [ris]) (01/18/90)

Here is another BUG report from Denmark.

I am using:	g++ 1.36.3-
based on:	gcc 1.36
under:		Ultrix V2.2-1 Worksystem V1.1 System #2
on a:		DEC VAXstation 2000

The compiler gets a fatal signal 11 (segmentation fault) when compiling a
certain line in a program. The following sample session will show what is
displayed by the compiler as well as what I specify for it:

****** SAMPLE SESSION START ******
% g++ -v id.cc -O -S
g++ version 1.36.3- (based on GCC 1.36)
 /usr/local/lib/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dvax -Dunix -D__vax__ -D__unix__ -D__OPTIMIZE__ id.cc /usr/tmp/cc020610.cpp
GNU CPP version 1.36
 /usr/local/lib/gcc-cc1plus /usr/tmp/cc020610.cpp -quiet -dumpbase id.cc -O -version -o id.s
GNU C++ version 1.36.3- (based on GCC 1.36) (vax) compiled by GNU C version 1.36.
default target switches: -munix
id.cc: In method IDtable_repr::~IDtable_repr ():
id.cc:43: Segmentation violation
g++: Program cc1plus got fatal signal 11.
******* SAMPLE SESSION END *******

I will just add that the BUG also occurs without optimisation !!

I have included the source code after preprocessing it, but I've also taken a
trip into GDB to what happens. The signal arrives (according to GDB) in line
2203 of 'cplus-parse.y' from which I have extracted the below piece of code:

******* CODE EXTRACT START *******
2190 stmt:
  :
  :
2197	| expr ';'
2198		{ emit_line_note (input_filename, lineno);
2199		  /* Do default conversion if safe and possibly important,
2200		     in case within ({...}).  */
2201		  if ((TREE_CODE (TREE_TYPE ($1)) == ARRAY_TYPE
2202		       && lvalue_p ($1))
2203		      || TREE_CODE (TREE_TYPE ($1)) == FUNCTION_TYPE)
2204		    $1 = default_conversion ($1);
2205		  expand_cplus_expr_stmt ($1);
2206		  clear_momentary ();
2207		  finish_stmt (); }
******** CODE EXTRACT END ********

I short disassembly, however, shows that the failing instruction occurs before
the call of  lvalue_p  in an attempt to compare something with the literal
constant '17' (ARRAY_TYPE ???). The other compare operand is in a memory
location with an offset of  12 from a register  and the register contains a
huge address beyond anything. This information should be as correct as it can
be.

To me it seems that the TREE_CODE extraction fails, but that's only a guess !!

Hope the above helps, that was the intention.


	You'll probably hear from me sooner rather than later
	the bugs bites hard and often these days.

	Jesper Jorgensen	jj@idris.id.dk

	Research associate
	Department of Computer Science
	Technical University of Denmark
	DK-2800 Lyngby
	DENMARK


****** PREPROCESSED CODE START ******
# 1 "id.cc"
 

# 1 "id.hh" 1
 

 















#pragma once
# 1 "/usr/local/lib/g++-include/std.h" 1
 
 























#pragma once


# 1 "/usr/local/lib/g++-include/stdio.h" 1
 
 





















 




























#pragma once


 






















# 108 "/usr/local/lib/g++-include/stdio.h"














 
 

 


extern  struct  _iobuf {
    int      _cnt;
    char*    _ptr;
    char*    _base;

    int     _bufsiz;
    short   _flag;








    char    _file;






} _iob[];










# 171 "/usr/local/lib/g++-include/stdio.h"
































extern "C" {

int    _doprnt(const char*, void*,     struct _iobuf *);
int    _doscan(    struct _iobuf *, const char*, ...);
int    _filbuf(    struct _iobuf *);
int    _flsbuf(unsigned,     struct _iobuf *);
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 *);
int    fread(void*, int, int,     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  *);
int    fwrite(const void*, int, int,     struct _iobuf *);
char*  gets(char*);
int    getw(    struct _iobuf *);
int    pclose(    struct _iobuf *);
    struct _iobuf *  popen(const char*, const char*);
int    printf(const char* ...);
void   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);
void   setlinebuf(    struct _iobuf *);
void   setvbuf(    struct _iobuf *, char*, int, int);
int    sscanf(char*, const char* ...);
    struct _iobuf *  tmpfile();
int    ungetc(int,     struct _iobuf *);
int    vfprintf(    struct _iobuf *, const char*, ...);

 
 

int    vprintf(const char*, ... );





char*  sprintf(char*, const char* ...);
char*  vsprintf(char*, const char*, ...);


}
















# 29 "/usr/local/lib/g++-include/std.h" 2


extern "C" {
void volatile _exit(int);
void volatile abort(void);
 
int       access(const char*, int);
int       acct(const char*);
unsigned  alarm(unsigned);
double    atof(const char*);
int       atoi(const char*);
long      atol(const char*);
int       bind(int, void*, int);
int       brk(void*);
int       bsearch (const void *, const void *, unsigned long, 
                   unsigned long, auto int (*ptf)(const void*, const void*));
void*     calloc(unsigned, unsigned);
void      cfree(void*);
int       chdir(const char*);
int       chmod(const char*, int);
int       chown(const char*, int, int);
long      clock(void);
int       close(int);
int       creat(const char*, unsigned long int);
char*     crypt(const char*, const char*);
char*     ctermid(char*);
char*     cuserid(char*);
double    drand48(void);
int       dup(int);
int       dup2(int, int);
int       dysize(int);
char*     ecvt(double, int, int*, int*);
char*     encrypt(char*, int);
double    erand(short*);
int       execl(const char*, const char *, ...);
int       execle(const char*, const char *, ...);
int       execlp(const char*, const char*, ...);
int       exect(const char*,  const char**,  char**);
int       execv(const char*,  const char**);
int       execve(const char*, const char**, char**);
int       execvp(const char*,  const char**);
void volatile exit(int);
int       fchmod(int, int);
int       fchown(int, int, int);
int       fcntl(int, int, ...);
char*     fcvt(double, int, int*, int*);
int       ffs(int);
int       flock(int, int);
int       fork(void);
void      free(void*);
int       fsync(int);
long      ftok(const char*, int);
int       ftruncate(int, unsigned long);
char*     gcvt(double, int, char*);
char*     getcwd(char*, int);
int       getdomainname(char*, int);
int       getdtablesize(void);
int       getegid(void);
char*     getenv(const char*);
int       geteuid(void);
int       getgid(void);
int       getgroups(int, int*);
long      gethostid(void);
int       gethostname(char*, int);
char*     getlogin(void);
int       getopt(int, char**, char*);
int       getpagesize(void);
char*     getpass(const char*);
int       getpgrp(void);
int       getpid(void);
int       getppid(void);
int       getpriority(int, int);
int       getpw(int, char*);
unsigned  getuid(void);
char*     getwd(char*);
char*     initstate(unsigned, char*, int);
int       ioctl(int, int, char*);
int       isatty(int);
long      jrand48(short*);
int       kill(int, int);
int       killpg(int, int);
void      lcong48(short*);
int       link(const char*, const char*);
int       listen(int, int);
int       lock(int, int, long);
long      lrand48(void);
long      lseek(int, long, int);
void*     malloc(unsigned);
void*     memalign(unsigned, unsigned);
void*     memccpy(void*, const void*, int, int);
void*     memchr(const void*, int, int);
int       memcmp(const void*, const void*, int);
void*     memcpy(void*, const void*, int);
void*     memset(void*, int, int);
int       mkdir(const char*, int);
int       mknod(const char*, int, int);
int       mkstemp(char*);
char*     mktemp(char*);
long      mrand48(void);
int       nice(int);
long      nrand48(short*);
int       open(const char*, int, ...);
void      pause(void);
void      perror(const char*);
int       pipe(int*);
void      profil(char*, int, int, int);
int       psignal(unsigned, char*);
int       ptrace(int, int, int, int);
int       putenv(const char*);
int       qsort(void*, int, unsigned, auto (*ptf)(void*,void*));
int       rand(void);
long      random(void);
int       read(int, void*, unsigned);
int       readlink(const char*, char*, int);
void*     realloc(void*, unsigned);
int       rename(const char*, const char*);
int       rmdir(const char*);               
void*     sbrk(int);              
short*    seed48(short*);
int       send(int, char*, int, int);
int       setgid(int);
int       sethostname(char*, int);
int       setkey(const char*);
int       setpgrp(int, int);
int       setpriority(int, int, int);
int       setregid(int, int);
int       setreuid(int, int);
char*     setstate(char*);
int       setuid(int);
int       sigblock(int);
int       siginterrupt(int, int);
int       sigpause(int);
int       sigsetmask(int);
unsigned  sleep(unsigned);
int       socket(int, int, int);
int       srand(int);
void      srand48(long);
void      srandom(int);
int       stime(long*);
char*     strcat(char*, const char*);
char*     strchr(const char*, int);
int       strcmp(const char*, const char*);
char*     strcpy(char*, const char*);
int       strcspn(const char*, const char*);
char*     strdup(const char*);
int       strlen(const char*);
char*     strncat(char*, const char*, int);
int       strncmp(const char*, const char*, int);
char*     strncpy(char*, const char*, int);
char*     strpbrk(const char*, const char*);
char*     strrchr(const char*, int);
int       strspn(const char*, const char*);
double    strtod(const char*, char**);
char*     strtok(char*, const char*);
long      strtol(const char*, char**, int);
void      swab(void*, void*, int);
int       symlink(const char*, const char*);
int       syscall(int, ...);
int       system(const char*);
char*     tempnam(char*, char*);
int       tgetent(char*, char*);
int       tgetnum(char*);
int       tgetflag(char*);
char*     tgetstr(char *, char **);
char*     tgoto(char*, int, int);
long      time(long*);
char*     tmpnam(char*);
int       tputs(char *, int, auto int (*)());
int       truncate(const char*, unsigned long);
char*     ttyname(int);
int       ttyslot(void);
unsigned  ualarm(unsigned, unsigned);
long      ulimit(int, long);
int       umask(int);
int       unlink(const char*);
unsigned  usleep(unsigned);
int       vadvise(int);
void*     valloc(unsigned);
int       vfork(void);
int       vhangup(void);
int       wait(int*);
int       write(int, const void*, unsigned);


}









extern "C" {
int       bcmp(const void*, const void*, int);
void      bcopy(const void*, void*, int);
void      bzero(void*, int);
char*     index(const char*, int);
char*     rindex(const char*, int);
}


extern char**   environ;
extern volatile int errno;
extern char*    sys_errlist[];
extern int      sys_nerr;                  
extern char*    optarg;
extern int      opterr;
extern int      optind;


extern "C" void* alloca(unsigned long);





# 20 "id.hh" 2

# 1 "/usr/local/lib/g++-include/values.h" 1
 
 























#pragma once





















# 140 "/usr/local/lib/g++-include/values.h"






















# 21 "id.hh" 2

# 1 "../adminclasses.hh" 1
 

 















#pragma once




















# 22 "id.hh" 2

# 1 "../referclasses.hh" 1
 

 
















#pragma once
# 1 "../refcount.hh" 1
 

 















#pragma once

class RefCount {
  int count ;
  RefCount(const RefCount &) ;
  RefCount operator=(const RefCount &) ;
public:
  RefCount() ;
  ~RefCount() ;
  int operator++() ;
  int operator--() ;
  operator int() const ;
} ;
# 44 "../refcount.hh"

inline RefCount::RefCount()
  { count = 1 ; }
inline RefCount::~RefCount()
  { }
inline int RefCount::operator++()
  { return ++count ; }
inline int RefCount::operator--()
  { return --count ; }
inline RefCount::operator int() const
  { return count ; }





# 21 "../referclasses.hh" 2
























# 57 "../referclasses.hh"


# 23 "id.hh" 2




 
class IDvalue {
public:
  virtual ~IDvalue() { }
} ;



 
 
 
class IDvalinc {

  friend class  ID ;
  friend class  ID_repr ;

  IDvalinc *_next ;			 
  IDvalue  *_value ;			 

 
   IDvalinc(const IDvalinc &)  ;	 ~IDvalinc()  ;	 IDvalinc operator=(const IDvalinc &)  ;	 IDvalinc *operator&()   ;
  IDvalinc(IDvalinc *, IDvalue *) ;

} ;

inline     IDvalinc::~IDvalinc() 
  { delete _value ; }			 
inline IDvalinc::IDvalinc(IDvalinc *_next1, IDvalue *_value1)
  { _next = _next1 ;    _value = _value1 ; }



 
class ID_repr {

  friend class  IDtable ;
  friend class  IDtable_repr ;
   ID_repr(const ID_repr &)  ;	 ~ID_repr()  ;	 ID_repr operator=(const ID_repr &)  ;	 ID_repr *operator&()   ;	RefCount refc ;	friend class ID  ;

  ID_repr    *_nextn ;			 
  ID_repr    *_nexto ;			 
  IDvalinc   *_fstinc ;			 
  const char *_name ;			 
  int         ord ;			 
  ID_repr    *_check ;			 

 
  ID_repr(ID_repr *, ID_repr *, const char *, int) ;

} ;

inline     ID_repr::~ID_repr()  {	 
  for(IDvalinc *_nexti, *_thisi=_fstinc ; _thisi ; _thisi=_nexti )
    { _nexti = _thisi->_next ; delete _thisi ; }
  delete _name ;			 
}
inline ID_repr::ID_repr(ID_repr *_nextn1, ID_repr *_nexto1,
			const char *_name1, int ord1) {
  _nextn  = _nextn1 ;   _nexto = _nexto1 ;
  _fstinc = 0 ;         _name  = strcpy(new char[ strlen(_name1)+1 ], _name1) ;
   ord    = ord1 ;      _check = this ;	 
}



 
class ID {

  friend class  IDtable ;
  ID_repr *_repr ;	void cleanup_repr() ;	void deref_repr() ;	int not_unique_deref_repr() ;	void ref_repr() const ;	ID(ID_repr *)  ; ;

public:

 
  ID() ;	ID(const ID &) ;	~ID() ;	ID operator=(const ID &) ;	int OK() const  ;

 
  int valid() const ;			 
  const char *name() const ;		 
  int ord() const ;			 

 
  void push_value(IDvalue *_value1) ;
  int has_value() const ;
  void pop_value() ;			 
  const IDvalue *value() const ;

} ;

inline void ID::cleanup_repr()
  {   }

inline void ID::deref_repr()	{ if (_repr && !--_repr->refc) { cleanup_repr() ; delete _repr ; } ; } inline int ID::not_unique_deref_repr()	{ return _repr && _repr->refc>1 ? --_repr->refc : 0 ; }	inline void ID::ref_repr() const { if (_repr) ++_repr->refc ; }	inline ID::ID(ID_repr *_repr1) { _repr = _repr1 ; }	inline ID::ID() { _repr = 0 ; } inline ID::ID(const ID &x) { _repr = x._repr ; ref_repr() ; }	inline ID::~ID() { deref_repr() ; }	inline ID ID::operator=(const ID &x)	{ x.ref_repr() ; deref_repr() ; _


repr = x._repr ; return *this ; }	inline int ID::OK() const { return _repr != 0 ; }  ;

inline int ID::valid() const		 
  { return _repr && _repr->_check==_repr ; }
inline const char *ID::name() const	 
  { return _repr && _repr->_check==_repr ? _repr->_name : 0 ; }
inline int ID::ord() const		 
  { return _repr && _repr->_check==_repr ? _repr->ord :      (1 << (     (8  * (int)sizeof(int))   - 1))  ; }

inline void ID::push_value(IDvalue *_value1) {
  if (_repr && _repr->_check==_repr)
    _repr->_fstinc = new IDvalinc( _repr->_fstinc, _value1 ) ;
}
inline int ID::has_value() const
  { return _repr && _repr->_check==_repr && _repr->_fstinc ; }
inline void ID::pop_value() {
  if (_repr && _repr->_check==_repr) {
    IDvalinc *_oldinc = _repr->_fstinc ; 
    if (_oldinc) {
      _repr->_fstinc = _oldinc->_next ;
      delete _oldinc ;			 
    }
  }
}
inline const IDvalue *ID::value() const
  { return _repr && _repr->_check==_repr && _repr->_fstinc
      ? _repr->_fstinc->_value : 0 ; }



 
class IDtable_repr {

   IDtable_repr(const IDtable_repr &)  ;	 ~IDtable_repr()  ;	 IDtable_repr operator=(const IDtable_repr &)  ;	 IDtable_repr *operator&()   ;	RefCount refc ;	friend class IDtable  ;

  int      noel ;			 
  ID_repr *_firstn ;			 
  ID_repr *_firsto ;			 
  ID_repr *_latestn ;			 
  ID_repr *_latesto ;			 

 
  IDtable_repr(ID_repr *) ;

} ;

inline IDtable_repr::IDtable_repr(ID_repr *_first) {
   noel   = 1 ;				 
  _firstn = _firsto  = _latestn = _latesto = _first ;
}



 
class IDtable {

  IDtable_repr *_repr ;	void cleanup_repr() ;	void deref_repr() ;	int not_unique_deref_repr() ;	void ref_repr() const ;	IDtable(IDtable_repr *)  ;

 
  int lookup_name(const char*, ID_repr *&, ID_repr *&) const ;
  int lookup_ord (int, ID_repr *&, ID_repr *&) const ;

public:

 
  IDtable() ;	IDtable(const IDtable &) ;	~IDtable() ;	IDtable operator=(const IDtable &) ;	int OK() const  ;

 
  int noel() const ;			 

 
  ID insert(const char *, int) ;	 

 
  ID operator[](const char *_name1) const ;
  ID operator[](int ord1) const ;




} ;

inline void IDtable::deref_repr()	{ if (_repr && !--_repr->refc) { cleanup_repr() ; delete _repr ; } ; } inline int IDtable::not_unique_deref_repr()	{ return _repr && _repr->refc>1 ? --_repr->refc : 0 ; }	inline void IDtable::ref_repr() const { if (_repr) ++_repr->refc ; }	inline IDtable::IDtable(IDtable_repr *_repr1) { _repr = _repr1 ; }	inline IDtable::IDtable() { _repr = 0 ; } inline IDtable::IDtable(const IDtable &x) { _repr = x._repr ; ref_repr() ; }	inline IDtable::~IDtable() { deref_repr() ; }	inlin


e IDtable IDtable::operator=(const IDtable &x)	{ x.ref_repr() ; deref_repr() ; _repr = x._repr ; return *this ; }	inline int IDtable::OK() const { return _repr != 0 ; }  ;	 

inline int IDtable::noel() const	 
  { return _repr ? _repr->noel : 0 ; }

inline ID IDtable::operator[](const char *_name1) const {
  ID_repr *_pn, *_cn, *_this ;		 
  if (!_repr || lookup_name(_name1,_pn,_cn))
    _this = 0 ;
  else					 
    (_this = (_repr->_latestn=_cn))->refc++ ;
  return _this ;
}
inline ID IDtable::operator[](int ord1) const {
  ID_repr *_po, *_co, *_this ;		 
  if (!_repr || lookup_ord (ord1,_po,_co))
    _this = 0 ;
  else					 
    (_this = (_repr->_latesto=_co))->refc++ ;
  return _this ;
}



# 3 "id.cc" 2




# 36 "id.cc"



    IDtable_repr::~IDtable_repr()  {
  for(ID_repr *_nextn, *_thisn=_firstn ; _thisn ; _thisn=_nextn ) {
    _nextn = _thisn->_nextn ;		 
    _thisn->_check = 0 ;		 
    ID(_thisn) ;			 
  }					 
}					 


 
 
 
 
 
 
 
 
 
 
 
 
int IDtable::lookup_name(const char *_name1,
			 ID_repr *&_prevn, ID_repr *&_currn) const {
  int result ; ID_repr *_startn ;

  _prevn = 0 ; result = 1 ;		 
  _startn = _repr->_latestn ;		 
  do {
    for(_currn = _startn ;		 
	_currn && ((result = strcmp(_name1,_currn->_name)) > 0) ;
	_currn = (_prevn = _currn)->_nextn ) ;
  } while (_startn != _repr->_firstn &&	 
	   result<0 && !_prevn &&	 
	   (_startn = _repr->_firstn)) ; 

  return result ;			 
}


 
 
int IDtable::lookup_ord(int ord1, ID_repr* &_prevo, ID_repr* &_curro) const {
  int result ; ID_repr *_starto ;

  _prevo = 0 ; result = 1 ;
  _starto = _repr->_latesto ;
  do {
    for(_curro = _starto ;
	_curro && ((result = ord1-_curro->ord) > 0) ;
	_curro = (_prevo = _curro)->_nexto ) ;
  } while (_starto != _repr->_firsto &&
	   result<0 && !_prevo &&
	   (_starto = _repr->_firsto)) ;

  return result ;
}


ID IDtable::insert(const char *_name1, int ord1) {
  ID_repr *_prevn, *_currn ;		 
  ID_repr *_prevo, *_curro ;		 
  ID_repr *_this ;			 

   
  if (!_repr)
    _repr = new IDtable_repr(_this = new ID_repr( 0, 0, _name1, ord1 )) ;
  else
    if (lookup_name(_name1, _prevn, _currn) &&
	lookup_ord (  ord1, _prevo, _curro) ) {
      _this = new ID_repr( _currn, _curro, _name1, ord1 ) ;
      if (_prevn) _prevn->_nextn = _this ; 
             else _repr->_firstn = _this ; 
      if (_prevo) _prevo->_nexto = _this ; 
             else _repr->_firsto = _this ; 
      _repr->_latestn = _this ;		 
      _repr->_latesto = _this ;
      _repr->noel++ ;			 
    }
    else				 
      _this = 0 ;

  if (_this) _this->refc++ ;		 
  return _this ;			 
}
******* PREPROCESSED CODE END *******