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
commit 0bacdf5fdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 4 deletions

View file

@ -259,6 +259,11 @@ proc listGcUnsafety(s: PSym; onlyWarning: bool; cycleCheck: var IntSet; conf: Co
of routineKinds: of routineKinds:
# recursive call *always* produces only a warning so the full error # recursive call *always* produces only a warning so the full error
# message is printed: # message is printed:
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) listGcUnsafety(u, true, cycleCheck, conf)
message(conf, s.info, msgKind, message(conf, s.info, msgKind,
"'$#' is not GC-safe as it calls '$#'" % "'$#' is not GC-safe as it calls '$#'" %
@ -836,6 +841,9 @@ proc trackCall(tracked: PEffects; n: PNode) =
discard discard
var effectList = op.n[0] var effectList = op.n[0]
if a.kind == nkSym and a.sym.kind == skMethod: 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) propagateEffects(tracked, n, a.sym)
elif isNoEffectList(effectList): elif isNoEffectList(effectList):
if isForwardedProc(a): 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())