From 01389b5eb9704e7ecbf5785b5c10ce952f87e8cf Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Tue, 1 Apr 2025 15:37:54 +0800 Subject: [PATCH] `conv` needs to be picky about aliases and introduces a temp for `addr conv` (#24818) ref https://github.com/nim-lang/Nim/pull/24817 ref https://github.com/nim-lang/Nim/pull/24815 ref https://github.com/status-im/nim-eth/pull/784 ```nim {.emit:""" void foo(unsigned long long* x) { } """.} proc foo(x: var culonglong) {.importc: "foo", nodecl.} proc main(x: var uint64) = # var s: culonglong = u # TODO: var m = uint64(12) # var s = culonglong(m) foo(culonglong m) var u = uint64(12) main(u) ``` Notes that this code gives incompatible errors in 2.0.0, 2.2.0 and the devel branch. With this PR, `conv` is kept, but it seems to go back to https://github.com/nim-lang/Nim/pull/24807 (cherry picked from commit f9c8775783c98094615a90760b2ae9a4aca03c70) --- compiler/ccgcalls.nim | 4 ++-- compiler/ccgexprs.nim | 14 +++++++++++--- compiler/types.nim | 2 +- tests/ccgbugs/taddrconvs.nim | 27 +++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 tests/ccgbugs/taddrconvs.nim diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 0bf16ba9f8..bc0613afde 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -307,7 +307,7 @@ proc withTmpIfNeeded(p: BProc, a: TLoc, needsTmp: bool): TLoc = else: result = a -proc literalsNeedsTmp(p: BProc, a: TLoc): TLoc = +proc expressionsNeedsTmp(p: BProc, a: TLoc): TLoc = result = getTemp(p, a.lode.typ, needsInit=false) genAssignment(p, result, a, {}) @@ -326,7 +326,7 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode; result: var Rope; need (optByRef notin param.options or not p.module.compileToCpp): a = initLocExpr(p, n) if n.kind in {nkCharLit..nkNilLit}: - addAddrLoc(p.config, literalsNeedsTmp(p, a), result) + addAddrLoc(p.config, expressionsNeedsTmp(p, a), result) else: addAddrLoc(p.config, withTmpIfNeeded(p, a, needsTmp), result) elif p.module.compileToCpp and param.typ.kind in {tyVar} and diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 35207ca488..a848928574 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -808,6 +808,11 @@ proc cowBracket(p: BProc; n: PNode) = proc cow(p: BProc; n: PNode) {.inline.} = if n.kind == nkHiddenAddr: cowBracket(p, n[0]) +template ignoreConv(e: PNode): bool = + let destType = e.typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink}) + let srcType = e[1].typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink}) + sameBackendTypePickyAliases(destType, srcType) + proc genAddr(p: BProc, e: PNode, d: var TLoc) = # careful 'addr(myptrToArray)' needs to get the ampersand: if e[0].typ.skipTypes(abstractInstOwned).kind in {tyRef, tyPtr}: @@ -820,7 +825,11 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) = d.lode = e else: var a: TLoc = initLocExpr(p, e[0]) - putIntoDest(p, d, e, addrLoc(p.config, a), a.storage) + if e[0].kind in {nkHiddenStdConv, nkHiddenSubConv, nkConv} and not ignoreConv(e[0]): + # addr (conv x) introduces a temp because `conv x` is not a rvalue + putIntoDest(p, d, e, addrLoc(p.config, expressionsNeedsTmp(p, a)), a.storage) + else: + putIntoDest(p, d, e, addrLoc(p.config, a), a.storage) template inheritLocation(d: var TLoc, a: TLoc) = if d.k == locNone: d.storage = a.storage @@ -2253,8 +2262,7 @@ proc genRangeChck(p: BProc, n: PNode, d: var TLoc) = [getTypeDesc(p.module, dest), rdCharLoc(a)], a.storage) proc genConv(p: BProc, e: PNode, d: var TLoc) = - let destType = e.typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink}) - if sameBackendTypeIgnoreRange(destType, e[1].typ): + if ignoreConv(e): expr(p, e[1], d) else: genSomeCast(p, e, d) diff --git a/compiler/types.nim b/compiler/types.nim index 2acb164d4d..9853cf1222 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1420,7 +1420,7 @@ proc sameBackendTypeIgnoreRange*(x, y: PType): bool = proc sameBackendTypePickyAliases*(x, y: PType): bool = var c = initSameTypeClosure() - c.flags.incl {IgnoreTupleFields, PickyCAliases, PickyBackendAliases} + c.flags.incl {IgnoreTupleFields, IgnoreRangeShallow, PickyCAliases, PickyBackendAliases} c.cmp = dcEqIgnoreDistinct result = sameTypeAux(x, y, c) diff --git a/tests/ccgbugs/taddrconvs.nim b/tests/ccgbugs/taddrconvs.nim new file mode 100644 index 0000000000..6990648c4a --- /dev/null +++ b/tests/ccgbugs/taddrconvs.nim @@ -0,0 +1,27 @@ +discard """ + targets: "c cpp" + matrix: "--mm:refc; --mm:orc" +""" + +{.emit:""" +void foo(unsigned long long* x) +{ +} +""".} + +block: + proc foo(x: var culonglong) {.importc: "foo", nodecl.} + + proc main(x: var uint64) = + foo(culonglong x) + + var u = uint64(12) + main(u) + +block: + proc foo(x: var culonglong) {.importc: "foo", nodecl.} + + proc main() = + var m = uint64(12) + foo(culonglong(m)) + main()