Skip to content

Commit

Permalink
Bug [a366c6efee]
Browse files Browse the repository at this point in the history
  • Loading branch information
apnadkarni committed Jul 16, 2023
1 parent 3fb975f commit ccf857a
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 7 deletions.
4 changes: 2 additions & 2 deletions generic/tclInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -2606,8 +2606,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
Expand Down
15 changes: 10 additions & 5 deletions generic/tclListObj.c
Original file line number Diff line number Diff line change
Expand Up @@ -3448,16 +3448,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;
}
Expand Down
9 changes: 9 additions & 0 deletions tests/lreplace.test
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ccf857a

Please sign in to comment.