james@bigtex.uucp (James Van Artsdalen) (09/22/88)
I have isolate a piece of code in which gcc handles incorrectly with inline functions. I am in the midst of changing jobs and can't devote any more time to it, but this should be sufficient as an example. The compiler is an unmodified 1.28 with tm-i386v.h and config-i386v.h. The sample is a piece of Larry Wall's perl program. The two functions were moved from perly.c into their own file, bad.c. When bad.c is compiled with inline functions, perl dumps core, but without inline functions, perl runs fine (output is deleted because it is large, correct and not interesting). Comparing the assembly from compiling bad.c with and without inline functions hints that gcc may be losing track of the number of pushes onto the stack, but this shouldn't cause a core dump in these functions I would think. /usr4/src/perl> gcc -c -O -finline-functions bad.c /usr4/src/perl> make gcc perly.o arg.o array.o cmd.o dump.o eval.o form.o hash.o regexp.o stab.o str.o toke.o util.o version.o yow.o bad.o perl.o -lm -o perl touch all /usr4/src/perl> ./perl t/op.stat Memory fault - core dumped (ERR:139) /usr4/src/perl> gcc -c -O bad.c /usr4/src/perl> make gcc perly.o arg.o array.o cmd.o dump.o eval.o form.o hash.o regexp.o stab.o str.o toke.o util.o version.o yow.o bad.o perl.o -lm -o perl touch all /usr4/src/perl> ./perl t/op.stat [ output deleted ] /usr4/src/perl> Here is the file bad.c: ----- extern char *memcpy(); typedef struct { int _cnt; unsigned char *_ptr; unsigned char *_base; char _flag; char _file; } FILE; typedef struct arg ARG; typedef struct cmd CMD; typedef struct formcmd FCMD; typedef struct scanpat SPAT; typedef struct stab STAB; typedef struct stio STIO; typedef struct sub SUBR; typedef struct string STR; typedef struct atbl ARRAY; typedef struct htbl HASH; typedef unsigned short line_t; char *safemalloc(); struct stab { struct stab *stab_next; char *stab_name; STR *stab_val; struct stio *stab_io; FCMD *stab_form; ARRAY *stab_array; HASH *stab_hash; SUBR *stab_sub; char stab_flags; }; struct stio { FILE *fp; long lines; long page; long page_len; long lines_left; char *top_name; STAB *top_stab; char *fmt_name; STAB *fmt_stab; short subprocess; char type; char flags; }; union argptr { ARG *arg_arg; char *arg_cval; STAB *arg_stab; SPAT *arg_spat; CMD *arg_cmd; STR *arg_str; double arg_nval; }; struct arg { union argptr arg_ptr; short arg_len; unsigned char arg_type; unsigned char arg_flags; }; struct acmd { STAB *ac_stab; ARG *ac_expr; }; struct ccmd { CMD *cc_true; CMD *cc_alt; }; struct cmd { CMD *c_next; ARG *c_expr; CMD *c_head; STR *c_short; STAB *c_stab; SPAT *c_spat; char *c_label; union ucmd { struct acmd acmd; struct ccmd ccmd; } ucmd; short c_slen; short c_flags; char *c_file; line_t c_line; char c_type; }; ARG *op_new(); ARG *make_op(); ARG *l(); extern STAB *defstab ; void free_arg(); ARG * stab2arg(atype,stab) int atype; register STAB *stab; { register ARG *arg; arg = op_new(1); arg->arg_type = 1 ; arg[1].arg_type = atype; arg[1].arg_ptr.arg_stab = stab; return arg; } CMD * wopt(cmd) register CMD *cmd; { register CMD *tail; register ARG *arg = cmd->c_expr; STAB *asgnstab; if (arg && arg->arg_type == 1 && arg[1].arg_type == 8 ) { cmd->c_flags &= ~077 ; cmd->c_flags |= 6 ; cmd->c_stab = arg[1].arg_ptr.arg_stab; if (arg[1].arg_ptr.arg_stab->stab_io->flags & 1 ) { cmd->c_expr = l(make_op(9 , 2, stab2arg(4 ,defstab), arg, ((ARG*)0 ) ,1 )); } else { free_arg(arg); cmd->c_expr = ((ARG*)0 ) ; } } else if (arg && arg->arg_type == 1 && arg[1].arg_type == 16 ) { cmd->c_flags &= ~077 ; cmd->c_flags |= 11 ; cmd->c_stab = arg[1].arg_ptr.arg_stab; free_arg(arg); cmd->c_expr = ((ARG*)0 ) ; } else if (arg && arg->arg_type == 1 && arg[1].arg_type == 14 ) { if ((cmd->c_flags & 077 ) == 10 ) asgnstab = cmd->c_stab; else asgnstab = defstab; cmd->c_expr = l(make_op(9 , 2, stab2arg(4 ,asgnstab), arg, ((ARG*)0 ) ,1 )); cmd->c_flags &= ~077 ; } if (cmd->ucmd.ccmd.cc_true == ((CMD*)0 ) ) return cmd; for (tail = cmd->ucmd.ccmd.cc_true; tail->c_next; tail = tail->c_next) ; if (cmd->ucmd.ccmd.cc_alt != ((CMD*)0 ) ) { tail->c_next = cmd->ucmd.ccmd.cc_alt; for ( ; tail->c_next; tail = tail->c_next) ; } tail->c_next = (CMD *) safemalloc(sizeof (CMD)); tail = tail->c_next; if (!cmd->ucmd.ccmd.cc_alt) cmd->ucmd.ccmd.cc_alt = tail; memcpy( (char *)tail,(char *)cmd, sizeof(CMD)); ; tail->c_type = 3 ; tail->c_flags ^= 04000 ; tail->c_next = tail->ucmd.ccmd.cc_true; tail->ucmd.acmd.ac_expr = make_op(67 ,0,((ARG*)0 ) ,((ARG*)0 ) ,((ARG*)0 ) ,0); tail->ucmd.acmd.ac_stab = ((STAB*)0 ) ; return cmd; } -- James R. Van Artsdalen ...!uunet!utastro!bigtex!james "Live Free or Die" Home: 512-346-2444 Work: 328-0282; 110 Wild Basin Rd. Ste #230, Austin TX 78746