summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--interpret.h16
-rw-r--r--pc/ChangeLog4
-rw-r--r--pc/Makefile.tst8
-rw-r--r--test/ChangeLog3
-rw-r--r--test/Makefile.am6
-rw-r--r--test/Makefile.in11
-rw-r--r--test/Maketests5
-rw-r--r--test/fieldassign.awk1
-rw-r--r--test/fieldassign.in2
-rw-r--r--test/fieldassign.ok2
11 files changed, 59 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 055515c3..f5a33e0c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,11 @@
reproducer.
Also, update the copyright year.
+ * interpret.h (r_interpret): Op_assign case, don't unref the
+ old lhs NODE until after the assignment. See test case in
+ the comment in the code and test/fieldassign.awk. Thanks to
+ Yasuhiro Yamada <yamada@gr3.ie> for the report.
+
2023-01-22 Arnold D. Robbins <arnold@skeeve.com>
* main.c: Update copyright year.
diff --git a/interpret.h b/interpret.h
index dff76ec2..3d663bf1 100644
--- a/interpret.h
+++ b/interpret.h
@@ -874,16 +874,30 @@ mod:
break;
case Op_assign:
+ {
+ NODE *save_lhs;
+
lhs = POP_ADDRESS();
r = TOP_SCALAR();
- unref(*lhs);
+ /*
+ * 1/2023:
+ * The old NODE pointed to by *lhs has to be freed.
+ * But we can't free it too early, in case it's both $0 and $1
+ * (Test case was gawk 'gsub(/./, "@") && $0=$1'). So we save
+ * the old one, and after the assignment, we free it, since
+ * $0 and $1 have the same stptr value but only $0 has MALLOC
+ * in the flags. Whew!
+ */
+ save_lhs = *lhs;
if (r->type == Node_elem_new) {
DEREF(r);
r = dupnode(Nnull_string);
}
UPREF(r);
UNFIELD(*lhs, r);
+ unref(save_lhs);
REPLACE(r);
+ }
break;
case Op_subscript_assign:
diff --git a/pc/ChangeLog b/pc/ChangeLog
index 1a84a1ae..d45600d5 100644
--- a/pc/ChangeLog
+++ b/pc/ChangeLog
@@ -1,3 +1,7 @@
+2023-01-31 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.tst: Regenerated.
+
2022-11-25 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.tst: Regenerated.
diff --git a/pc/Makefile.tst b/pc/Makefile.tst
index b475005c..1cb6f869 100644
--- a/pc/Makefile.tst
+++ b/pc/Makefile.tst
@@ -153,7 +153,8 @@ BASIC_TESTS = \
delarprm delfunc dfacheck2 dfamb1 dfastress divzero divzero2 \
dynlj eofsplit \
eofsrc1 escapebrace exit2 exitval1 exitval2 exitval3 fcall_exit \
- fcall_exit2 fldchg fldchgnf fldterm fnamedat fnarray fnarray2 \
+ fcall_exit2 \
+ fieldassign fldchg fldchgnf fldterm fnamedat fnarray fnarray2 \
fnaryscl fnasgnm fnmisc fordel forref forsimp fsbs fscaret fsnul1 \
fsrs fsspcoln fstabplus funsemnl funsmnam funstack getline \
getline2 getline3 getline4 getline5 getlnbuf getlnfa getnr2tb \
@@ -1628,6 +1629,11 @@ fcall_exit2:
@-AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+fieldassign:
+ @echo $@
+ @-AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
fldchg:
@echo $@
@-AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/ChangeLog b/test/ChangeLog
index 1da93514..97cfd1c6 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -4,6 +4,9 @@
* elemnew1.awk, elemnew1.ok: New files.
Also, update the copyright year.
+ * Makefile.am (EXTRA_DIST): New test: fieldassign.
+ * fieldassign.awk, fieldassign.in, fieldassign.ok: New files.
+
2023-01-22 Arnold D. Robbins <arnold@skeeve.com>
* makepmafile.c (main): Make the file mode 0600.
diff --git a/test/Makefile.am b/test/Makefile.am
index 09e56e92..24ae6787 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -318,6 +318,9 @@ EXTRA_DIST = \
fcall_exit2.ok \
fflush.ok \
fflush.sh \
+ fieldassign.awk \
+ fieldassign.in \
+ fieldassign.ok \
fieldwdth.awk \
fieldwdth.in \
fieldwdth.ok \
@@ -1459,7 +1462,8 @@ BASIC_TESTS = \
delarprm delfunc dfacheck2 dfamb1 dfastress divzero divzero2 \
dynlj eofsplit \
eofsrc1 escapebrace exit2 exitval1 exitval2 exitval3 fcall_exit \
- fcall_exit2 fldchg fldchgnf fldterm fnamedat fnarray fnarray2 \
+ fcall_exit2 \
+ fieldassign fldchg fldchgnf fldterm fnamedat fnarray fnarray2 \
fnaryscl fnasgnm fnmisc fordel forref forsimp fsbs fscaret fsnul1 \
fsrs fsspcoln fstabplus funsemnl funsmnam funstack getline \
getline2 getline3 getline4 getline5 getlnbuf getlnfa getnr2tb \
diff --git a/test/Makefile.in b/test/Makefile.in
index b5d1d9e6..8feff4ee 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -586,6 +586,9 @@ EXTRA_DIST = \
fcall_exit2.ok \
fflush.ok \
fflush.sh \
+ fieldassign.awk \
+ fieldassign.in \
+ fieldassign.ok \
fieldwdth.awk \
fieldwdth.in \
fieldwdth.ok \
@@ -1727,7 +1730,8 @@ BASIC_TESTS = \
delarprm delfunc dfacheck2 dfamb1 dfastress divzero divzero2 \
dynlj eofsplit \
eofsrc1 escapebrace exit2 exitval1 exitval2 exitval3 fcall_exit \
- fcall_exit2 fldchg fldchgnf fldterm fnamedat fnarray fnarray2 \
+ fcall_exit2 \
+ fieldassign fldchg fldchgnf fldterm fnamedat fnarray fnarray2 \
fnaryscl fnasgnm fnmisc fordel forref forsimp fsbs fscaret fsnul1 \
fsrs fsspcoln fstabplus funsemnl funsmnam funstack getline \
getline2 getline3 getline4 getline5 getlnbuf getlnfa getnr2tb \
@@ -3390,6 +3394,11 @@ fcall_exit2:
@-AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+fieldassign:
+ @echo $@
+ @-AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
fldchg:
@echo $@
@-AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/Maketests b/test/Maketests
index 98245c37..5d7dcee3 100644
--- a/test/Maketests
+++ b/test/Maketests
@@ -327,6 +327,11 @@ fcall_exit2:
@-AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+fieldassign:
+ @echo $@
+ @-AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
fldchg:
@echo $@
@-AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/fieldassign.awk b/test/fieldassign.awk
new file mode 100644
index 00000000..631775b1
--- /dev/null
+++ b/test/fieldassign.awk
@@ -0,0 +1 @@
+gsub(/./, "@") && $0 = $1
diff --git a/test/fieldassign.in b/test/fieldassign.in
new file mode 100644
index 00000000..5f5521fa
--- /dev/null
+++ b/test/fieldassign.in
@@ -0,0 +1,2 @@
+abc
+def
diff --git a/test/fieldassign.ok b/test/fieldassign.ok
new file mode 100644
index 00000000..11e9cfd5
--- /dev/null
+++ b/test/fieldassign.ok
@@ -0,0 +1,2 @@
+@@@
+@@@