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:
|
if elem.isMetaType:
|
||||||
owner.flags.incl tfHasMeta
|
owner.flags.incl tfHasMeta
|
||||||
|
|
||||||
if owner.kind != tyProc:
|
if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
|
||||||
if elem.isGCedMem or tfHasGCedMem in elem.flags:
|
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
|
owner.flags.incl tfHasGCedMem
|
||||||
|
|
||||||
proc rawAddSon*(father, son: PType) =
|
proc rawAddSon*(father, son: PType) =
|
||||||
|
|
|
||||||
|
|
@ -209,8 +209,7 @@ proc useVar(a: PEffects, n: PNode) =
|
||||||
a.init.add s.id
|
a.init.add s.id
|
||||||
if {sfGlobal, sfThread} * s.flags == {sfGlobal} and s.kind in {skVar, skLet}:
|
if {sfGlobal, sfThread} * s.flags == {sfGlobal} and s.kind in {skVar, skLet}:
|
||||||
if s.guard != nil: guardGlobal(a, n, s.guard)
|
if s.guard != nil: guardGlobal(a, n, s.guard)
|
||||||
if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem) and
|
if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem):
|
||||||
tfGcSafe notin s.typ.flags:
|
|
||||||
if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n)
|
if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n)
|
||||||
markGcUnsafe(a)
|
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