diff options
| author | apnadkarni <apnmbx-wits@yahoo.com> | 2023-07-16 07:23:13 (GMT) |
|---|---|---|
| committer | apnadkarni <apnmbx-wits@yahoo.com> | 2023-07-16 07:23:13 (GMT) |
| commit | 7791d13f5c7e5c514bdce1e27760d30100e38375 (patch) | |
| tree | 3577b39399916930e9b7e3d2538d59b913096f2a | |
| parent | 56ca2a64d7665bc088790e6cfa134b39a7d0034f (diff) | |
| parent | ccf857a3db566e41ba8167be6442441cdf92a9e3 (diff) | |
| download | tcl-7791d13f5c7e5c514bdce1e27760d30100e38375.zip tcl-7791d13f5c7e5c514bdce1e27760d30100e38375.tar.gz tcl-7791d13f5c7e5c514bdce1e27760d30100e38375.tar.bz2 | |
Merge 8.7 - Bug [a366c6efee]
| -rw-r--r-- | generic/tclInt.h | 4 | ||||
| -rw-r--r-- | generic/tclListObj.c | 15 | ||||
| -rw-r--r-- | tests/lreplace.test | 9 |
3 files changed, 21 insertions, 7 deletions
diff --git a/generic/tclInt.h b/generic/tclInt.h index d7941fb..9c7ad17 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2672,8 +2672,8 @@ typedef struct ListRep { * (1) No string representation exists which means it will obviously have * to be generated from the list representation when needed * (2) The ListStore flags is marked canonical. This is done at the time - * the string representation is generated from the list IF the list - * representation does not have a span (see comments in UpdateStringOfList). + * the string representation is generated from the list under certain + * conditions (see comments in UpdateStringOfList). * (3) The list representation does not have a span component. This is * because list Tcl_Obj's with spans are always created from existing lists * and never from strings (see SetListFromAny) and thus their string diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 143c476..1d5f7f1 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -3470,16 +3470,21 @@ UpdateStringOfList( * Mark the list as being canonical; although it will now have a string * rep, it is one we derived through proper "canonical" quoting and so * it's known to be free from nasties relating to [concat] and [eval]. - * However, we only do this if this is not a spanned list. Marking the - * storage canonical for a spanned list make ALL lists using the storage - * canonical which is not right. (Consider a list generated from a + * However, we only do this if + * + * (a) the store is not shared as a shared store may be referenced by + * multiple lists with different string reps. (see [a366c6efee]), AND + * + * (b) list does not have a span. Consider a list generated from a * string and then this function called for a spanned list generated - * from it). On the other hand, a spanned list is always canonical + * from the original list. We cannot mark the list store as canonical as + * that would also make the originating list canonical, which it may not + * be. On the other hand, the spanned list itself is always canonical * (never generated from a string) so it does not have to be explicitly * marked as such. The ListObjIsCanonical macro takes this into account. * See the comments there. */ - if (listRep.spanPtr == NULL) { + if (listRep.storePtr->refCount < 2 && listRep.spanPtr == NULL) { LIST_ASSERT(listRep.storePtr->firstUsed == 0);/* Invariant */ listRep.storePtr->flags |= LISTSTORE_CANONICAL; } diff --git a/tests/lreplace.test b/tests/lreplace.test index 009170e..55b3ee3 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -505,6 +505,15 @@ test ledit-5.2 {compiled lreplace: Bug 47ac84309b} { }} {a b c} } {a b A c} +test ledit-bug-a366c6efee {Bug [a366c6efee]} -body { + apply {{} { + set l { } + string length [ledit l 1 1]; # Force string generation + set result foo + append result " " bar + }} +} -result "foo bar" + # Testing for compiled behaviour. Far too many variations to check with # spelt-out tests. Note that this *just* checks whether the compiled version # and the interpreted version are the same, not whether the interpreted |
