summaryrefslogtreecommitdiff
path: root/Src/Modules
diff options
context:
space:
mode:
authorBart Schaefer <schaefer@zsh.org>2023-09-03 11:42:00 -0700
committerBart Schaefer <schaefer@zsh.org>2023-09-03 11:42:00 -0700
commit9ff1b2810e70658b2364b737478e9a996de0a644 (patch)
tree5b40cc9ed8601b7fcc6cdaef40eb2dba56571b66 /Src/Modules
parenta8853323dd631ba26869ea6e0bf1b8098247731d (diff)
downloadzsh-9ff1b2810e70658b2364b737478e9a996de0a644.tar.gz
zsh-9ff1b2810e70658b2364b737478e9a996de0a644.zip
users/29220: fix bug with assignment to private following explicit unset
Diffstat (limited to 'Src/Modules')
-rw-r--r--Src/Modules/param_private.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c
index e43f0edb4..8e04b2b95 100644
--- a/Src/Modules/param_private.c
+++ b/Src/Modules/param_private.c
@@ -230,7 +230,9 @@ setfn_error(Param pm)
* calling the original unsetfn. This assures that if the old unsetfn
* wants to use its getfn or setfn, they're unconditionally present.
* The "explicit" flag indicates that "unset" was called, if zero the
- * parameter is going out of scope (see params.c).
+ * parameter is going out of scope (see params.c). PM_DECLARED is
+ * asserted as if TYPESET_TO_UNSET were in use so that the private
+ * parameter is re-used rather than re-created when assigned again.
*
*/
@@ -268,9 +270,10 @@ pps_unsetfn(Param pm, int explicit)
pm->gsu.s = gsu;
if (locallevel <= pm->level)
gsu->unsetfn(pm, explicit);
- if (explicit)
+ if (explicit) {
+ pm->node.flags |= PM_DECLARED;
pm->gsu.s = (GsuScalar)c;
- else
+ } else
zfree(c, sizeof(struct gsu_closure));
}
@@ -307,9 +310,10 @@ ppi_unsetfn(Param pm, int explicit)
pm->gsu.i = gsu;
if (locallevel <= pm->level)
gsu->unsetfn(pm, explicit);
- if (explicit)
+ if (explicit) {
+ pm->node.flags |= PM_DECLARED;
pm->gsu.i = (GsuInteger)c;
- else
+ } else
zfree(c, sizeof(struct gsu_closure));
}
@@ -346,9 +350,10 @@ ppf_unsetfn(Param pm, int explicit)
pm->gsu.f = gsu;
if (locallevel <= pm->level)
gsu->unsetfn(pm, explicit);
- if (explicit)
+ if (explicit) {
+ pm->node.flags |= PM_DECLARED;
pm->gsu.f = (GsuFloat)c;
- else
+ } else
zfree(c, sizeof(struct gsu_closure));
}
@@ -386,9 +391,10 @@ ppa_unsetfn(Param pm, int explicit)
pm->gsu.a = gsu;
if (locallevel <= pm->level)
gsu->unsetfn(pm, explicit);
- if (explicit)
+ if (explicit) {
+ pm->node.flags |= PM_DECLARED;
pm->gsu.a = (GsuArray)c;
- else
+ } else
zfree(c, sizeof(struct gsu_closure));
}
@@ -427,9 +433,10 @@ pph_unsetfn(Param pm, int explicit)
pm->gsu.h = gsu;
if (locallevel <= pm->level)
gsu->unsetfn(pm, explicit);
- if (explicit)
+ if (explicit) {
+ pm->node.flags |= PM_DECLARED;
pm->gsu.h = (GsuHash)c;
- else
+ } else
zfree(c, sizeof(struct gsu_closure));
}