about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/options.yo3
-rw-r--r--Src/exec.c3
-rw-r--r--Src/math.c25
-rw-r--r--Test/E01options.ztst4
5 files changed, 38 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index b1fe74da4..2cd07ffa3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index abd0f8715..fbf65abbc 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -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
diff --git a/Src/exec.c b/Src/exec.c
index 109a04a26..da808d6f1 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -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;
diff --git a/Src/math.c b/Src/math.c
index 977e92345..56565a629 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -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) {
 	/*
diff --git a/Test/E01options.ztst b/Test/E01options.ztst
index 2b91b21fa..1caee8d24 100644
--- a/Test/E01options.ztst
+++ b/Test/E01options.ztst
@@ -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.