mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-20 01:48:31 +00:00
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 f9c8775783)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
27
tests/ccgbugs/taddrconvs.nim
Normal file
27
tests/ccgbugs/taddrconvs.nim
Normal file
@@ -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()
|
||||
Reference in New Issue
Block a user