summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--generic/tclCompCmds.c3
-rw-r--r--tests/dict.test51
3 files changed, 59 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index c0083d6..e28342b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2012-02-15 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (TclCompileDictForCmd): [Bug 3487626]: Fix
+ crash in compilation of [dict for] when its implementation command is
+ used directly rather than through the ensemble.
+
2012-02-09 Don Porter <dgp@users.sourceforge.net>
* generic/tclStringObj.c: Converted the memcpy() calls in append
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index 57a5370..18ff3dc 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -906,7 +906,7 @@ TclCompileDictForCmd(
* Compile the loop body itself. It should be stack-neutral.
*/
- SetLineInformation(4);
+ SetLineInformation(3);
CompileBody(envPtr, bodyTokenPtr, interp);
TclEmitOpcode( INST_POP, envPtr);
@@ -1112,6 +1112,7 @@ TclCompileDictUpdateCmd(
ExceptionRangeStarts(envPtr, range);
envPtr->currStackDepth++;
+ SetLineInformation(parsePtr->numWords - 1);
CompileBody(envPtr, bodyTokenPtr, interp);
envPtr->currStackDepth = savedStackDepth;
ExceptionRangeEnds(envPtr, range);
diff --git a/tests/dict.test b/tests/dict.test
index 5a2b609..5277cf6 100644
--- a/tests/dict.test
+++ b/tests/dict.test
@@ -1470,6 +1470,57 @@ test dict-22.23 {dict with: compiled} {
return $a,$b
}}
} 1,2
+
+proc linenumber {} {
+ dict get [info frame -1] line
+}
+test dict-23.1 {dict compilation crash: Bug 3487626} {
+ apply {n {
+ set e {}
+ set k {}
+ dict for {a b} {c {d {e {f g}}}} {
+ ::tcl::dict::for {h i} $b {
+ dict update i e j {
+ ::tcl::dict::update j f k {
+ return [expr {$n - [linenumber]}]
+ }
+ }
+ }
+ }
+ }} [linenumber]
+} 5
+test dict-23.2 {dict compilation crash: Bug 3487626} knownBug {
+ # Something isn't quite right in line number and continuation line
+ # tracking; at time of writing, this test produces 7, not 5, which
+ # indicates that the extra newlines in the non-script argument are
+ # confusing things.
+ apply {n {
+ set e {}
+ set k {}
+ dict for {a {
+b
+}} {c {d {e {f g}}}} {
+ ::tcl::dict::for {h {
+i
+}} ${
+b
+} {
+ dict update {
+i
+} e {
+j
+} {
+ ::tcl::dict::update {
+j
+} f k {
+ return [expr {$n - [linenumber]}]
+ }
+ }
+ }
+ }
+ }} [linenumber]
+} 5
+rename linenumber {}
# cleanup
::tcltest::cleanupTests