From 23b7a163f7b6a0045d826ed106d910edcc41bc12 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Wed, 7 Apr 2021 15:44:15 +0100 Subject: [PATCH] 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 --- src/cmd/ksh93/sh/init.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cmd/ksh93/sh/init.c b/src/cmd/ksh93/sh/init.c index b8d2466d6..6b68fce99 100644 --- a/src/cmd/ksh93/sh/init.c +++ b/src/cmd/ksh93/sh/init.c @@ -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) { - double d=1; + int d = 1; if(error_info.line >0) d = error_info.line; else if(error_info.context && error_info.context->line>0) d = error_info.context->line; NOT_USED(np); NOT_USED(fp); - return(d); + return((Sfdouble_t)d); } 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(); if(!val) { @@ -717,15 +717,15 @@ static void put_lineno(Namval_t* np,const char *val,int flags,Namfun_t *fp) return; } if(flags&NV_INTEGER) - n = *(double*)val; + n = (Sfdouble_t)(*(double*)val); else 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) { - register long n = nget_lineno(np,fp); + long n = (long)nget_lineno(np,fp); return(fmtbase(n, 10, 0)); }