mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-11 03:39:31 +00:00
fix #25976 Initialize tagEffects for proc types that declare .forbids but omit .tags, so they behave like explicit tags: [] during indirect-call effect tracking. Add a regression for the nested callback assignment case.
This commit is contained in:
@@ -1784,13 +1784,18 @@ proc setEffectsForProcType*(g: ModuleGraph; t: PType, n: PNode; s: PSym = nil) =
|
||||
elif s != nil and (s.magic != mNone or {sfImportc, sfExportc} * s.flags == {sfImportc}):
|
||||
effects[exceptionEffects] = newNodeI(nkArgList, effects.info)
|
||||
|
||||
let forbidsSpec = effectSpec(n, wForbids)
|
||||
let tagsSpec = effectSpec(n, wTags)
|
||||
if not isNil(tagsSpec):
|
||||
effects[tagEffects] = tagsSpec
|
||||
elif not isNil(forbidsSpec):
|
||||
# `.forbids` without `.tags` still declares a known empty tag set.
|
||||
# Leaving this as nil would mean "unknown tags", which later widens
|
||||
# indirect calls to `RootEffect`.
|
||||
effects[tagEffects] = newNodeI(nkArgList, effects.info)
|
||||
elif s != nil and (s.magic != mNone or {sfImportc, sfExportc} * s.flags == {sfImportc}):
|
||||
effects[tagEffects] = newNodeI(nkArgList, effects.info)
|
||||
|
||||
let forbidsSpec = effectSpec(n, wForbids)
|
||||
if not isNil(forbidsSpec):
|
||||
effects[forbiddenEffects] = forbidsSpec
|
||||
elif s != nil and (s.magic != mNone or {sfImportc, sfExportc} * s.flags == {sfImportc}):
|
||||
|
||||
28
tests/effects/tissue25976.nim
Normal file
28
tests/effects/tissue25976.nim
Normal file
@@ -0,0 +1,28 @@
|
||||
type
|
||||
NestedPoll = object of RootEffect
|
||||
|
||||
CallbackFunc = proc(arg: pointer) {.gcsafe, raises: [], forbids: [NestedPoll].}
|
||||
TaggedCallbackFunc = proc(arg: pointer) {.gcsafe, raises: [], tags: [], forbids: [NestedPoll].}
|
||||
|
||||
InternalAsyncCallback = object
|
||||
fn: CallbackFunc
|
||||
|
||||
TaggedInternalAsyncCallback = object
|
||||
fn: TaggedCallbackFunc
|
||||
|
||||
proc closeSocket(aftercb: CallbackFunc = nil) =
|
||||
proc continuation(udata: pointer) =
|
||||
aftercb(nil)
|
||||
|
||||
let acb = InternalAsyncCallback(fn: continuation)
|
||||
discard acb
|
||||
|
||||
proc closeSocketTagged(aftercb: TaggedCallbackFunc = nil) =
|
||||
proc continuation(udata: pointer) =
|
||||
aftercb(nil)
|
||||
|
||||
let acb = TaggedInternalAsyncCallback(fn: continuation)
|
||||
discard acb
|
||||
|
||||
closeSocket()
|
||||
closeSocketTagged()
|
||||
Reference in New Issue
Block a user