From 75b512bc6a8526f0a9f71af1cbdf769aa58da3f9 Mon Sep 17 00:00:00 2001 From: metagn Date: Sat, 16 Nov 2024 12:43:58 +0300 Subject: [PATCH] prevent codegen of inactive case fields in VM object constructor nodes (#24442) fixes #17571 Objects in the VM are represented as object constructor nodes that contain every single field, including ones in different case branches. This is so that every field has a unique invariant index in the object constructor that can be written to and read from. However when converting this node back into semantic code, fields from inactive case branches can remain in the constructor which causes bad codegen, generating assignments to fields from other case branches. To fix this, fields from inactive branches are now detected in `semmacrosanity.annotateType` (called in `fixupTypeAfterEval`) and marked to prevent the codegen of their assignments. In #24441 these fields were excluded from the resulting node, but this causes issues when the node is directly supposed to go back into the VM, for example as `const` values. I don't know if this is the only case where this happens, so I wasn't sure about how to keep that implementation working. --- compiler/ccgexprs.nim | 4 +++ compiler/semmacrosanity.nim | 64 +++++++++++++++++++++++++++++++------ tests/vm/tcaseobj.nim | 19 +++++++++++ 3 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 tests/vm/tcaseobj.nim diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 1c4bbd885d..f5ce39f7a5 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1835,6 +1835,10 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = discard getTypeDesc(p.module, t) let ty = getUniqueType(t) for i in 1..