fixes #2257
This commit is contained in:
parent
f9a3de984d
commit
bc264618f5
4 changed files with 93 additions and 32 deletions
|
|
@ -1335,8 +1335,12 @@ proc propagateToOwner*(owner, elem: PType) =
|
|||
if elem.isMetaType:
|
||||
owner.flags.incl tfHasMeta
|
||||
|
||||
if owner.kind != tyProc:
|
||||
if elem.isGCedMem or tfHasGCedMem in elem.flags:
|
||||
if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
|
||||
tyGenericInvocation}:
|
||||
let elemB = elem.skipTypes({tyGenericInst})
|
||||
if elemB.isGCedMem or tfHasGCedMem in elemB.flags:
|
||||
# for simplicity, we propagate this flag even to generics. We then
|
||||
# ensure this doesn't bite us in sempass2.
|
||||
owner.flags.incl tfHasGCedMem
|
||||
|
||||
proc rawAddSon*(father, son: PType) =
|
||||
|
|
|
|||
|
|
@ -209,8 +209,7 @@ proc useVar(a: PEffects, n: PNode) =
|
|||
a.init.add s.id
|
||||
if {sfGlobal, sfThread} * s.flags == {sfGlobal} and s.kind in {skVar, skLet}:
|
||||
if s.guard != nil: guardGlobal(a, n, s.guard)
|
||||
if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem) and
|
||||
tfGcSafe notin s.typ.flags:
|
||||
if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem):
|
||||
if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n)
|
||||
markGcUnsafe(a)
|
||||
|
||||
|
|
|
|||
26
tests/parallel/tarray_of_channels.nim
Normal file
26
tests/parallel/tarray_of_channels.nim
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# bug #2257
|
||||
import threadpool
|
||||
|
||||
type StringChannel = TChannel[string]
|
||||
var channels: array[1..3, StringChannel]
|
||||
|
||||
type
|
||||
MyObject[T] = object
|
||||
x: T
|
||||
|
||||
var global: MyObject[string]
|
||||
var globalB: MyObject[float]
|
||||
|
||||
proc consumer(ix : int) {.thread.} =
|
||||
echo channels[ix].recv() ###### not GC-safe: 'channels'
|
||||
echo globalB
|
||||
|
||||
proc main =
|
||||
for ix in 1..3: channels[ix].open()
|
||||
for ix in 1..3: spawn consumer(ix)
|
||||
for ix in 1..3: channels[ix].send("test")
|
||||
sync()
|
||||
for ix in 1..3: channels[ix].close()
|
||||
|
||||
when isMainModule:
|
||||
main()
|
||||
32
tests/parallel/tgc_unsafe.nim
Normal file
32
tests/parallel/tgc_unsafe.nim
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
discard """
|
||||
errormsg: "'consumer' is not GC-safe"
|
||||
line: 19
|
||||
"""
|
||||
|
||||
# bug #2257
|
||||
import threadpool
|
||||
|
||||
type StringChannel = TChannel[string]
|
||||
var channels: array[1..3, StringChannel]
|
||||
|
||||
type
|
||||
MyObject[T] = object
|
||||
x: T
|
||||
|
||||
var global: MyObject[string]
|
||||
var globalB: MyObject[float]
|
||||
|
||||
proc consumer(ix : int) {.thread.} =
|
||||
echo channels[ix].recv() ###### not GC-safe: 'channels'
|
||||
echo global
|
||||
echo globalB
|
||||
|
||||
proc main =
|
||||
for ix in 1..3: channels[ix].open()
|
||||
for ix in 1..3: spawn consumer(ix)
|
||||
for ix in 1..3: channels[ix].send("test")
|
||||
sync()
|
||||
for ix in 1..3: channels[ix].close()
|
||||
|
||||
when isMainModule:
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue