summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2016-03-17 13:19:44 (GMT)
committerdgp <dgp@users.sourceforge.net>2016-03-17 13:19:44 (GMT)
commit3bd42df4a43bf78791b9ed88f0f32b29d9fbc9ac (patch)
tree8279d93d0ad3263adc96b13cbc12ad087caa318e
parent91a20bc018f04bcf8ce13412ad16cfcbe9e53489 (diff)
parentbfa7cb3c5d224a86a6136bc063018638eb3b9a0b (diff)
downloadtcl-3bd42df4a43bf78791b9ed88f0f32b29d9fbc9ac.zip
tcl-3bd42df4a43bf78791b9ed88f0f32b29d9fbc9ac.tar.gz
tcl-3bd42df4a43bf78791b9ed88f0f32b29d9fbc9ac.tar.bz2
merge 8.6 bug fixes
-rw-r--r--generic/tclCompCmdsGR.c4
-rw-r--r--generic/tclCompile.c21
-rw-r--r--generic/tclEnsemble.c43
-rw-r--r--tests/compile.test11
4 files changed, 67 insertions, 12 deletions
diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c
index e674fb0..87ed745 100644
--- a/generic/tclCompCmdsGR.c
+++ b/generic/tclCompCmdsGR.c
@@ -2966,10 +2966,12 @@ IndexTailVarIfKnown(
} else {
full = 0;
lastTokenPtr = varTokenPtr + n;
- if (!TclWordKnownAtCompileTime(lastTokenPtr, tailPtr)) {
+
+ if (lastTokenPtr->type != TCL_TOKEN_TEXT) {
Tcl_DecrRefCount(tailPtr);
return -1;
}
+ Tcl_SetStringObj(tailPtr, lastTokenPtr->start, lastTokenPtr->size);
}
tailName = TclGetStringFromObj(tailPtr, &len);
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index 4c259ab..c0b5dcc 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -3360,26 +3360,25 @@ TclGetInnermostExceptionRange(
int returnCode,
ExceptionAux **auxPtrPtr)
{
- int exnIdx = -1, i;
+ int i = envPtr->exceptArrayNext;
+ ExceptionRange *rangePtr = envPtr->exceptArrayPtr + i;
- for (i=0 ; i<envPtr->exceptArrayNext ; i++) {
- ExceptionRange *rangePtr = &envPtr->exceptArrayPtr[i];
+ while (i > 0) {
+ rangePtr--; i--;
if (CurrentOffset(envPtr) >= rangePtr->codeOffset &&
(rangePtr->numCodeBytes == -1 || CurrentOffset(envPtr) <
rangePtr->codeOffset+rangePtr->numCodeBytes) &&
(returnCode != TCL_CONTINUE ||
envPtr->exceptAuxArrayPtr[i].supportsContinue)) {
- exnIdx = i;
+
+ if (auxPtrPtr) {
+ *auxPtrPtr = envPtr->exceptAuxArrayPtr + i;
+ }
+ return rangePtr;
}
}
- if (exnIdx == -1) {
- return NULL;
- }
- if (auxPtrPtr) {
- *auxPtrPtr = &envPtr->exceptAuxArrayPtr[exnIdx];
- }
- return &envPtr->exceptArrayPtr[exnIdx];
+ return NULL;
}
/*
diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c
index 8f7d1a2..986a553 100644
--- a/generic/tclEnsemble.c
+++ b/generic/tclEnsemble.c
@@ -3082,6 +3082,11 @@ TclAttemptCompileProc(
Tcl_Token *saveTokenPtr = parsePtr->tokenPtr;
int savedStackDepth = envPtr->currStackDepth;
unsigned savedCodeNext = envPtr->codeNext - envPtr->codeStart;
+ int savedAuxDataArrayNext = envPtr->auxDataArrayNext;
+ int savedExceptArrayNext = envPtr->exceptArrayNext;
+#ifdef TCL_COMPILE_DEBUG
+ int savedExceptDepth = envPtr->exceptDepth;
+#endif
DefineLineInformation;
if (cmdPtr->compileProc == NULL) {
@@ -3130,7 +3135,45 @@ TclAttemptCompileProc(
* we avoid compiling subcommands that recursively call TclCompileScript().
*/
+#ifdef TCL_COMPILE_DEBUG
+ if (envPtr->exceptDepth != savedExceptDepth) {
+ Tcl_Panic("ExceptionRange Starts and Ends do not balance");
+ }
+#endif
+
if (result != TCL_OK) {
+ ExceptionAux *auxPtr = envPtr->exceptAuxArrayPtr;
+
+ for (i = 0; i < savedExceptArrayNext; i++) {
+ while (auxPtr->numBreakTargets > 0
+ && auxPtr->breakTargets[auxPtr->numBreakTargets - 1]
+ >= savedCodeNext) {
+ auxPtr->numBreakTargets--;
+ }
+ while (auxPtr->numContinueTargets > 0
+ && auxPtr->continueTargets[auxPtr->numContinueTargets - 1]
+ >= savedCodeNext) {
+ auxPtr->numContinueTargets--;
+ }
+ auxPtr++;
+ }
+ envPtr->exceptArrayNext = savedExceptArrayNext;
+
+ if (savedAuxDataArrayNext != envPtr->auxDataArrayNext) {
+ AuxData *auxDataPtr = envPtr->auxDataArrayPtr;
+ AuxData *auxDataEnd = auxDataPtr;
+
+ auxDataPtr += savedAuxDataArrayNext;
+ auxDataEnd += envPtr->auxDataArrayNext;
+
+ while (auxDataPtr < auxDataEnd) {
+ if (auxDataPtr->type->freeProc != NULL) {
+ auxDataPtr->type->freeProc(auxDataPtr->clientData);
+ }
+ auxDataPtr++;
+ }
+ envPtr->auxDataArrayNext = savedAuxDataArrayNext;
+ }
envPtr->currStackDepth = savedStackDepth;
envPtr->codeNext = envPtr->codeStart + savedCodeNext;
#ifdef TCL_COMPILE_DEBUG
diff --git a/tests/compile.test b/tests/compile.test
index 6ef697c..6aa7fd1 100644
--- a/tests/compile.test
+++ b/tests/compile.test
@@ -224,6 +224,17 @@ test compile-5.2 {TclCompileForeachCmd: non-local variables} {
foreach-test
set ::foo
} 3
+test compile-5.3 {TclCompileForeachCmd: [Bug b9b2079e6d]} -setup {
+ proc demo {} {
+ foreach x y {
+ if 1 break else
+ }
+ }
+} -body {
+ demo
+} -cleanup {
+ rename demo {}
+} -returnCodes error -result {wrong # args: no script following "else" argument}
test compile-6.1 {TclCompileSetCmd: global scalar names with ::s} -setup {
catch {unset x}