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 *******