fixes #20515; base method requires explicit {.gcsafe.} to be GC-safe (#20574)

* fixes #20515; base requires explicit `{.gcsafe.}` to be GC-safe

* add tests
This commit is contained in:
ringabout
2022-10-16 19:20:05 +08:00
committed by GitHub
parent 619d6c318c
commit 0bacdf5fdf
2 changed files with 32 additions and 4 deletions

View File

@@ -259,10 +259,15 @@ proc listGcUnsafety(s: PSym; onlyWarning: bool; cycleCheck: var IntSet; conf: Co
of routineKinds:
# recursive call *always* produces only a warning so the full error
# message is printed:
listGcUnsafety(u, true, cycleCheck, conf)
message(conf, s.info, msgKind,
"'$#' is not GC-safe as it calls '$#'" %
[s.name.s, u.name.s])
if u.kind == skMethod and {sfBase, sfThread} * u.flags == {sfBase}:
message(conf, u.info, msgKind,
"Base method '$#' requires explicit '{.gcsafe.}' to be GC-safe" %
[u.name.s])
else:
listGcUnsafety(u, true, cycleCheck, conf)
message(conf, s.info, msgKind,
"'$#' is not GC-safe as it calls '$#'" %
[s.name.s, u.name.s])
of skParam, skForVar:
message(conf, s.info, msgKind,
"'$#' is not GC-safe as it performs an indirect call via '$#'" %
@@ -836,6 +841,9 @@ proc trackCall(tracked: PEffects; n: PNode) =
discard
var effectList = op.n[0]
if a.kind == nkSym and a.sym.kind == skMethod:
if {sfBase, sfThread} * a.sym.flags == {sfBase}:
if tracked.config.hasWarn(warnGcUnsafe): warnAboutGcUnsafe(n, tracked.config)
markGcUnsafe(tracked, a)
propagateEffects(tracked, n, a.sym)
elif isNoEffectList(effectList):
if isForwardedProc(a):

20
tests/method/t20515.nim Normal file
View File

@@ -0,0 +1,20 @@
discard """
errormsg: "Base method 'zzz' requires explicit '{.gcsafe.}' to be GC-safe"
line: 10
"""
type
A = ref object of RootObj
B = ref object of A
method zzz(a: A) {.base.} =
discard
var s: seq[int]
method zzz(a: B) =
echo s
proc xxx(someObj: A) {.gcsafe.} =
someObj.zzz()
xxx(B())