diff options
author | metagn <metagngn@gmail.com> | 2024-09-17 15:01:48 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-17 14:01:48 +0200 |
commit | 680a13a142e08782a111635a6f1692292d4f3354 (patch) | |
tree | 5616111bd74be54dcf8243173a09ea417c877776 | |
parent | 21a161a535d915d34cb5bd6c340b8acc8c64ed90 (diff) | |
download | Nim-680a13a142e08782a111635a6f1692292d4f3354.tar.gz |
fix segfault in effect tracking for sym node with nil type (#24114)
fixes #24112 Sym nodes in templates that could be open are [given `nil` type](https://github.com/nim-lang/Nim/blob/22d2cf217597468ace8ba540d6990b1f6d8a816a/compiler/semtempl.nim#L274) when `--experimentalOpenSym` is disabled so that they can be semchecked to give a warning since #24007. The first nodes of object constructors (in this case) and in type conversions don't replace their first node (the symbol) with a typechecked one, they only call `semTypeNode` on it and leave it as is. Effect tracking checks if the type of a sym node has a destructor to check if the node type should be replaced with the sym type. But this causes a segfault when the type of the node is nil. To fix this, we always set the node type to the sym type if the node type is nil. Alternatively `semObjConstr` and `semConv` could be changed to set the type of their first node to the found type but I'm not sure if this would break anything. They could call `semExprWithType` on the first node but `semTypeNode` would still have to be called (maybe call it before?). This isn't a problem if the sym node has a type but is just nested in `nkOpenSym` or `nkOpenSymChoice` which have nil type instead (i.e. with openSym enabled), so maybe this still is the "most general" solution, I don't know.
-rw-r--r-- | compiler/sempass2.nim | 2 | ||||
-rw-r--r-- | tests/template/t24112.nim | 19 |
2 files changed, 20 insertions, 1 deletions
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 467f300b5..0a160897f 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -1210,7 +1210,7 @@ proc track(tracked: PEffects, n: PNode) = if n.sym.typ != nil and tfHasAsgn in n.sym.typ.flags: tracked.owner.flags.incl sfInjectDestructors # bug #15038: ensure consistency - if not hasDestructor(n.typ) and sameType(n.typ, n.sym.typ): n.typ = n.sym.typ + if n.typ == nil or (not hasDestructor(n.typ) and sameType(n.typ, n.sym.typ)): n.typ = n.sym.typ of nkHiddenAddr, nkAddr: if n[0].kind == nkSym and isLocalSym(tracked, n[0].sym) and n.typ.kind notin {tyVar, tyLent}: diff --git a/tests/template/t24112.nim b/tests/template/t24112.nim new file mode 100644 index 000000000..175fc7d5e --- /dev/null +++ b/tests/template/t24112.nim @@ -0,0 +1,19 @@ +discard """ + matrix: "--skipParentCfg --filenames:legacyRelProj --hints:off" + action: reject +""" + +# issue #24112, needs --experimental:openSym disabled + +block: # simplified + type + SomeObj = ref object # Doesn't error if you make SomeObj be non-ref + template foo = yield SomeObj() + when compiles(foo): discard + +import std/asyncdispatch +block: + proc someProc(): Future[void] {.async.} = discard + proc foo() = + await someProc() #[tt.Error + ^ Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead]# |