Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[BUG & tentative PATCH] Invalid call to upscope in createparam



While I was looking into implementing the solution for hidden references, I found this call to upscope, which had to be wrong because it applies "base", a property of the referent, to the reference. Here is an example that fails because of this:

typeset -n ref=var1
() {
  typeset -n ref=var2
  ref=RESET
  typeset -p ref var1 var2
}
typeset -p ref var1 var2

Output:
(anon):typeset:3: no such variable: var2
typeset -n ref=var2
typeset -g var1=''
test.zsh:typeset:7: no such variable: var2
typeset -n ref=var1
typeset var1=''

Expected output:
(anon):typeset:3: no such variable: var1
typeset -n ref=var2
typeset -g var2=RESET
test.zsh:typeset:7: no such variable: var1
typeset -n ref=var1
typeset var2=RESET

The attached tentative patch removes the invalid call to upscope and changes the stop parameter passed to resolve_nameref. It now looks similar to the one found in setscope but the flags are different. I don't fully understand how the stop parameter works, so better double-check this.

The patch changes the behavior of one regression test. The new behavior looks correct to me.

Philippe

diff --git a/Src/params.c b/Src/params.c
index 7b515515e..1c37be012 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -1037,13 +1037,12 @@ createparam(char *name, int flags)
 	if (oldpm && !(flags & PM_NAMEREF) &&
 	    (oldpm->level == locallevel ?
 	     !(oldpm->node.flags & PM_RO_BY_DESIGN) : !(flags & PM_LOCAL)) &&
-	    (oldpm->node.flags & PM_NAMEREF) &&
-	    (oldpm = upscope(oldpm, oldpm->base))) {
+	    (oldpm->node.flags & PM_NAMEREF)) {
 	    Param lastpm;
 	    struct asgment stop;
 	    stop.flags = PM_NAMEREF | (flags & PM_LOCAL);
-	    stop.name = oldpm->node.nam;
-	    stop.value.scalar = GETREFNAME(oldpm);
+	    stop.name = "";
+	    stop.value.scalar = NULL;
 	    lastpm = (Param)resolve_nameref(oldpm, &stop);
 	    if (lastpm) {
 		if (lastpm->node.flags & PM_NAMEREF) {
diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst
index 54f0aaf68..a9345520f 100644
--- a/Test/K01nameref.ztst
+++ b/Test/K01nameref.ztst
@@ -862,6 +862,21 @@ F:Checking for a bug in zmodload that affects later tests
 >typeset -n ref=var
 >typeset -g var=RESET
 
+ unset -n ref
+ unset var1
+ typeset -n ref=var1
+ () {
+   typeset -n ref=var2
+   ref=RESET
+   typeset -p ref var2
+ }
+ typeset -p ref var2
+0:local reference hides same-name global reference
+>typeset -n ref=var2
+>typeset -g var2=RESET
+>typeset -n ref=var1
+>typeset -g var2=RESET
+
  unset -n ref
  unset one
  typeset -n ref
@@ -1031,9 +1046,8 @@ F:relies on global TYPESET_TO_UNSET in %prep
  () { typeset -n foo; foo=zz; local zz; foo=zz; print $bar $zz }
 0:regression: local nameref may not in-scope a global parameter
 F:previously this could create an infinite recursion and crash
->xx
 >xx zz
-*?*foo: assignment failed
+>xx
 
  typeset -nm foo=bar
 1:create nameref by pattern match not allowed


Messages sorted by: Reverse Date, Date, Thread, Author