36651: WARN_CREATE_GLOBAL += math expressions

Without this, '() { (( x=42 )) }' and '() { for (( i=0; … )) }' wouldn't warn
about $x and $i, respectively, being created global.
This commit is contained in:
Daniel Shahaf 2015-09-26 01:59:48 +00:00
parent 36abe20c0f
commit 2654cb43f6
5 changed files with 38 additions and 2 deletions

View File

@ -1,3 +1,8 @@
2015-09-27 Daniel Shahaf <d.s@daniel.shahaf.name>
* 36651: Doc/Zsh/options.yo Src/exec.c Src/math.c
Test/E01options.ztst: WARN_CREATE_GLOBAL += math expressions
2015-09-27 Matthew Martin <phy1729@gmail.com>
* 36653: Completion/Unix/Command/_user_admin: OpenBSD's usermod

View File

@ -746,7 +746,8 @@ pindex(NOWARNCREATEGLOBAL)
cindex(parameters, warning when created globally)
item(tt(WARN_CREATE_GLOBAL))(
Print a warning message when a global parameter is created in a function
by an assignment. This often indicates that a parameter has not been
by an assignment or in math context.
This often indicates that a parameter has not been
declared local when it should have been. Parameters explicitly declared
global from within a function using tt(typeset -g) do not cause a warning.
Note that there is no warning when a local parameter is assigned to in

View File

@ -176,7 +176,8 @@ mod_export int sfcontext;
/**/
struct execstack *exstack;
/* Stack with names of functions currently active. */
/* Stack with names of function calls, 'source' calls, and 'eval' calls
* currently active. */
/**/
mod_export Funcstack funcstack;

View File

@ -894,6 +894,24 @@ getcvar(char *s)
}
/* If script execution is inside a function call that hasn't returned,
* return the name of that function. Else return NULL.
*/
/**/
static const char *
in_function_call(void)
{
Funcstack i;
for (i = funcstack; i; i = i->prev)
if (i->tp == FS_FUNC) {
DPUTS(!i->name, "funcstack entry with no name");
return i->name;
}
return NULL;
}
/**/
static mnumber
setmathvar(struct mathvalue *mvp, mnumber v)
@ -929,6 +947,13 @@ setmathvar(struct mathvalue *mvp, mnumber v)
if (noeval)
return v;
untokenize(mvp->lval);
if (isset(WARNCREATEGLOBAL)) {
const char *function_name;
if (!paramtab->getnode(paramtab, mvp->lval) &&
(function_name = in_function_call()))
zwarn("math parameter %s created globally in function %s",
mvp->lval, function_name);
}
pm = setnparam(mvp->lval, v);
if (pm) {
/*

View File

@ -1110,11 +1110,15 @@
foo3=bar6
}
foo4=bar7 =true
(( foo5=8 ))
integer foo6=9
(( foo6=10 ))
}
fn
0:WARN_CREATE_GLOBAL option
?fn:3: scalar parameter foo1 created globally in function
?fn:5: scalar parameter foo1 created globally in function
?fn:15: math parameter foo5 created globally in function fn
# This really just tests if XTRACE is egregiously broken.
# To test it properly would need a full set of its own.