diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | interpret.h | 16 | ||||
-rw-r--r-- | pc/ChangeLog | 4 | ||||
-rw-r--r-- | pc/Makefile.tst | 8 | ||||
-rw-r--r-- | test/ChangeLog | 3 | ||||
-rw-r--r-- | test/Makefile.am | 6 | ||||
-rw-r--r-- | test/Makefile.in | 11 | ||||
-rw-r--r-- | test/Maketests | 5 | ||||
-rw-r--r-- | test/fieldassign.awk | 1 | ||||
-rw-r--r-- | test/fieldassign.in | 2 | ||||
-rw-r--r-- | test/fieldassign.ok | 2 |
11 files changed, 59 insertions, 4 deletions
@@ -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 @@ +@@@ +@@@ |