1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-15 04:32:24 +00:00

Fix implicit typecast mess in $LINENO discipline functions

On Ubuntu arm7, two variables.sh regression tests crashed with a
bus error (SIGBUS) in init.c on line 720 while testing $LINENO:

707 static void put_lineno(Namval_t* np,const char *val,int flags,Namfun_t *fp)
708 {
709	register long n;
710	Shell_t *shp = sh_getinterp();
711	if(!val)
712	{
713		fp = nv_stack(np, NIL(Namfun_t*));
714		if(fp && !fp->nofree)
715			free((void*)fp);
716		_nv_unset(np,NV_RDONLY);
717		return;
718	}
719	if(flags&NV_INTEGER)
720		n = *(double*)val;
721	else
722		n = sh_arith(shp,val);
723	shp->st.firstline += nget_lineno(np,fp)+1-n;
724 }

Apparently, gcc on arm7 doesn't like the implicit typecast from
double to long.

Those three $LINENO discipline functions are generally a mess of
implicit typecasts between Sfdouble_t, double, long and int.

Line numbers are internally stored as int. The discipline functions
need to use Sfdouble_t for API compatibility.

src/cmd/ksh93/sh/init.c: nget_lineno(), put_lineno(), get_lineno():
- Get rid of unnecessary implicit typecasts by adjusting the types
  of local variables.
- Make the typecasts that are done explicit.

Progresses: https://github.com/ksh93/ksh/issues/253
This commit is contained in:
Martijn Dekker 2021-04-07 15:44:15 +01:00
parent 6b9a668f98
commit 23b7a163f7

View file

@ -694,19 +694,19 @@ static char* get_rand(register Namval_t* np, Namfun_t *fp)
*/ */
static Sfdouble_t nget_lineno(Namval_t* np, Namfun_t *fp) static Sfdouble_t nget_lineno(Namval_t* np, Namfun_t *fp)
{ {
double d=1; int d = 1;
if(error_info.line >0) if(error_info.line >0)
d = error_info.line; d = error_info.line;
else if(error_info.context && error_info.context->line>0) else if(error_info.context && error_info.context->line>0)
d = error_info.context->line; d = error_info.context->line;
NOT_USED(np); NOT_USED(np);
NOT_USED(fp); NOT_USED(fp);
return(d); return((Sfdouble_t)d);
} }
static void put_lineno(Namval_t* np,const char *val,int flags,Namfun_t *fp) static void put_lineno(Namval_t* np,const char *val,int flags,Namfun_t *fp)
{ {
register long n; Sfdouble_t n;
Shell_t *shp = sh_getinterp(); Shell_t *shp = sh_getinterp();
if(!val) if(!val)
{ {
@ -717,15 +717,15 @@ static void put_lineno(Namval_t* np,const char *val,int flags,Namfun_t *fp)
return; return;
} }
if(flags&NV_INTEGER) if(flags&NV_INTEGER)
n = *(double*)val; n = (Sfdouble_t)(*(double*)val);
else else
n = sh_arith(shp,val); n = sh_arith(shp,val);
shp->st.firstline += nget_lineno(np,fp)+1-n; shp->st.firstline += (int)(nget_lineno(np,fp) + 1 - n);
} }
static char* get_lineno(register Namval_t* np, Namfun_t *fp) static char* get_lineno(register Namval_t* np, Namfun_t *fp)
{ {
register long n = nget_lineno(np,fp); long n = (long)nget_lineno(np,fp);
return(fmtbase(n, 10, 0)); return(fmtbase(n, 10, 0));
} }