mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Introduce usage of __builtin_unreachable() and noreturn (#248)
This commit adds an UNREACHABLE() macro that expands to either the __builtin_unreachable() compiler builtin (for release builds) or abort(3) (for development builds). This is used to mark code paths that are never to be reached. It also adds the 'noreturn' attribute to functions that never return: path_exec(), sh_done() and sh_syntax(). The UNREACHABLE() macro is not added after calling these. The purpose of these is: * to slightly improve GCC/Clang compiler optimizations; * to fix a few compiler warnings; * to add code clarity. Changes of note: src/cmd/ksh93/sh/io.c: outexcept(): - Avoid using __builtin_unreachable() here since errormsg can return despite using ERROR_system(1), as shp->jmplist->mode is temporarily set to 0. See: https://github.com/att/ast/issues/1336 src/cmd/ksh93/tests/io.sh: - Add a regression test for the ksh2020 bug referenced above. src/lib/libast/features/common: - Detect the existence of either the C11 stdnoreturn.h header or the GCC noreturn attribute, preferring the former when available. - Test for the existence of __builtin_unreachable(). Use it for release builds. On development builds, use abort() instead, which crahses reliably for debugging when unreachable code is reached. Co-authored-by: Martijn Dekker <martijn@inlv.org>
This commit is contained in:
parent
56913f8c2a
commit
c4f980eb29
87 changed files with 1170 additions and 122 deletions
|
|
@ -204,6 +204,7 @@ Namval_t *nv_addnode(Namval_t* np, int remove)
|
|||
nv_delete(sp->nodes[0],root,NV_NOFREE);
|
||||
dtinsert(root,sp->rp);
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_redef,sp->nodes[0]->nvname);
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
for(i=0; i < sp->numnodes; i++)
|
||||
|
|
@ -352,7 +353,10 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
|
|||
tp->com.comtyp = COMSCAN;
|
||||
}
|
||||
if(nv_isattr(np,NV_RDONLY) && np->nvfun && !(flags&NV_RDONLY))
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_readonly, nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(nv_isattr(np,NV_NOFREE) && nv_isnull(np))
|
||||
nv_offattr(np,NV_NOFREE);
|
||||
if(nv_istable(np))
|
||||
|
|
@ -413,6 +417,7 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
|
|||
{
|
||||
shp->mktype = 0;
|
||||
errormsg(SH_DICT,ERROR_exit(1),"%s: not a known type name",argv[0]);
|
||||
UNREACHABLE();
|
||||
}
|
||||
#endif /* SHOPT_TYPEDEF */
|
||||
if(!(arg->argflag&ARG_APPEND))
|
||||
|
|
@ -500,7 +505,10 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
|
|||
if(nv_isarray(np))
|
||||
{
|
||||
if((sub=nv_aimax(np)) < 0 && nv_arrayptr(np))
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_badappend,nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(sub>=0)
|
||||
sub++;
|
||||
}
|
||||
|
|
@ -928,7 +936,10 @@ Namval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
|
|||
}
|
||||
shp->first_root = root;
|
||||
if(nv_isref(np) && (c=='[' || c=='.' || !(flags&NV_ASSIGN)))
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_noref,nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(sub && c==0)
|
||||
{
|
||||
if(flags&NV_ARRAY)
|
||||
|
|
@ -1544,6 +1555,7 @@ skip:
|
|||
else if(c=='[')
|
||||
msg = e_noarray;
|
||||
errormsg(SH_DICT,ERROR_exit(1),msg,name);
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(fun.nofree&1)
|
||||
stakseek(offset);
|
||||
|
|
@ -1578,7 +1590,10 @@ void nv_putval(register Namval_t *np, const char *string, int flags)
|
|||
Namarr_t *ap;
|
||||
#endif /* SHOPT_FIXEDARRAY */
|
||||
if(!(flags&NV_RDONLY) && nv_isattr (np, NV_RDONLY))
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_readonly, nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
/*
|
||||
* The following could cause the shell to fork if assignment
|
||||
* would cause a side effect
|
||||
|
|
@ -2459,7 +2474,10 @@ void _nv_unset(register Namval_t *np,int flags)
|
|||
Namarr_t *ap;
|
||||
#endif /* SHOPT_FIXEDARRAY */
|
||||
if(!(flags&NV_RDONLY) && nv_isattr (np,NV_RDONLY))
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_readonly, nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(is_afunction(np) && np->nvalue.ip)
|
||||
{
|
||||
register struct slnod *slp = (struct slnod*)(np->nvenv);
|
||||
|
|
@ -2882,7 +2900,10 @@ Sfdouble_t nv_getnum(register Namval_t *np)
|
|||
nv_optimize(np);
|
||||
#endif /* SHOPT_OPTIMIZE */
|
||||
if(nv_istable(np))
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_number,nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(np->nvfun && np->nvfun->disc)
|
||||
{
|
||||
if(!nv_local)
|
||||
|
|
@ -2972,7 +2993,10 @@ void nv_newattr (register Namval_t *np, unsigned newatts, int size)
|
|||
|
||||
/* check for restrictions */
|
||||
if(sh_isoption(SH_RESTRICTED) && ((sp=nv_name(np))==nv_name(PATHNOD) || sp==nv_name(SHELLNOD) || sp==nv_name(ENVNOD) || sp==nv_name(FPATHNOD)))
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_restricted,nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
/* handle attributes that do not change data separately */
|
||||
n = np->nvflag;
|
||||
trans = !(n&NV_INTEGER) && (n&(NV_LTOU|NV_UTOL)); /* transcode to lower or upper case */
|
||||
|
|
@ -3267,11 +3291,17 @@ int nv_rename(register Namval_t *np, int flags)
|
|||
if(!(cp=nv_getval(np)))
|
||||
{
|
||||
if(flags&NV_MOVE)
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_varname,"");
|
||||
UNREACHABLE();
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
if(lastdot(cp,0) && nv_isattr(np,NV_MINIMAL))
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_varname,nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
arraynr = cp[strlen(cp)-1] == ']';
|
||||
if(nv_isarray(np) && !(mp=nv_opensub(np)))
|
||||
index=nv_aindex(np);
|
||||
|
|
@ -3393,7 +3423,10 @@ void nv_setref(register Namval_t *np, Dt_t *hp, int flags)
|
|||
if(nv_isref(np))
|
||||
return;
|
||||
if(nv_isarray(np))
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_badref,nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(!(cp=nv_getval(np)))
|
||||
{
|
||||
_nv_unset(np,0);
|
||||
|
|
@ -3401,7 +3434,10 @@ void nv_setref(register Namval_t *np, Dt_t *hp, int flags)
|
|||
return;
|
||||
}
|
||||
if((ep = lastdot(cp,0)) && nv_isattr(np,NV_MINIMAL))
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_badref,nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(hp)
|
||||
hpnext = dtvnext(hp);
|
||||
if((nr=nv_open(cp, hp?hp:shp->var_tree, flags|NV_NOSCOPE|NV_NOADD|NV_NOFAIL)))
|
||||
|
|
@ -3417,10 +3453,16 @@ void nv_setref(register Namval_t *np, Dt_t *hp, int flags)
|
|||
if(nr==np)
|
||||
{
|
||||
if(shp->namespace && nv_dict(shp->namespace)==hp)
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_selfref,nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
/* bind to earlier scope, or add to global scope */
|
||||
if(!(hp=dtvnext(hp)) || (nq=nv_search((char*)np,hp,NV_ADD|HASH_BUCKET))==np)
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_selfref,nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(nv_isarray(nq))
|
||||
nv_putsub(nq,(char*)0,ARRAY_UNDEF);
|
||||
}
|
||||
|
|
@ -3449,6 +3491,7 @@ void nv_setref(register Namval_t *np, Dt_t *hp, int flags)
|
|||
_nv_unset(np,NV_RDONLY);
|
||||
nv_onattr(np,NV_REF);
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_globalref,nv_name(np));
|
||||
UNREACHABLE();
|
||||
}
|
||||
shp->instance = 1;
|
||||
if(nq && !ep && (ap=nv_arrayptr(nq)) && !(ap->nelem&(ARRAY_UNDEF|ARRAY_SCAN)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue