Skip to content

Commit 01389b5

Browse files
ringaboutnarimiran
authored andcommitted
conv needs to be picky about aliases and introduces a temp for addr conv (#24818)
ref #24817 ref #24815 ref status-im/nim-eth#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 #24807 (cherry picked from commit f9c8775)
1 parent 210f747 commit 01389b5

File tree

4 files changed

+41
-6
lines changed

4 files changed

+41
-6
lines changed

compiler/ccgcalls.nim

+2-2
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ proc withTmpIfNeeded(p: BProc, a: TLoc, needsTmp: bool): TLoc =
307307
else:
308308
result = a
309309

310-
proc literalsNeedsTmp(p: BProc, a: TLoc): TLoc =
310+
proc expressionsNeedsTmp(p: BProc, a: TLoc): TLoc =
311311
result = getTemp(p, a.lode.typ, needsInit=false)
312312
genAssignment(p, result, a, {})
313313

@@ -326,7 +326,7 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode; result: var Rope; need
326326
(optByRef notin param.options or not p.module.compileToCpp):
327327
a = initLocExpr(p, n)
328328
if n.kind in {nkCharLit..nkNilLit}:
329-
addAddrLoc(p.config, literalsNeedsTmp(p, a), result)
329+
addAddrLoc(p.config, expressionsNeedsTmp(p, a), result)
330330
else:
331331
addAddrLoc(p.config, withTmpIfNeeded(p, a, needsTmp), result)
332332
elif p.module.compileToCpp and param.typ.kind in {tyVar} and

compiler/ccgexprs.nim

+11-3
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,11 @@ proc cowBracket(p: BProc; n: PNode) =
808808
proc cow(p: BProc; n: PNode) {.inline.} =
809809
if n.kind == nkHiddenAddr: cowBracket(p, n[0])
810810

811+
template ignoreConv(e: PNode): bool =
812+
let destType = e.typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink})
813+
let srcType = e[1].typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink})
814+
sameBackendTypePickyAliases(destType, srcType)
815+
811816
proc genAddr(p: BProc, e: PNode, d: var TLoc) =
812817
# careful 'addr(myptrToArray)' needs to get the ampersand:
813818
if e[0].typ.skipTypes(abstractInstOwned).kind in {tyRef, tyPtr}:
@@ -820,7 +825,11 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) =
820825
d.lode = e
821826
else:
822827
var a: TLoc = initLocExpr(p, e[0])
823-
putIntoDest(p, d, e, addrLoc(p.config, a), a.storage)
828+
if e[0].kind in {nkHiddenStdConv, nkHiddenSubConv, nkConv} and not ignoreConv(e[0]):
829+
# addr (conv x) introduces a temp because `conv x` is not a rvalue
830+
putIntoDest(p, d, e, addrLoc(p.config, expressionsNeedsTmp(p, a)), a.storage)
831+
else:
832+
putIntoDest(p, d, e, addrLoc(p.config, a), a.storage)
824833

825834
template inheritLocation(d: var TLoc, a: TLoc) =
826835
if d.k == locNone: d.storage = a.storage
@@ -2253,8 +2262,7 @@ proc genRangeChck(p: BProc, n: PNode, d: var TLoc) =
22532262
[getTypeDesc(p.module, dest), rdCharLoc(a)], a.storage)
22542263

22552264
proc genConv(p: BProc, e: PNode, d: var TLoc) =
2256-
let destType = e.typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink})
2257-
if sameBackendTypeIgnoreRange(destType, e[1].typ):
2265+
if ignoreConv(e):
22582266
expr(p, e[1], d)
22592267
else:
22602268
genSomeCast(p, e, d)

compiler/types.nim

+1-1
Original file line numberDiff line numberDiff line change
@@ -1420,7 +1420,7 @@ proc sameBackendTypeIgnoreRange*(x, y: PType): bool =
14201420

14211421
proc sameBackendTypePickyAliases*(x, y: PType): bool =
14221422
var c = initSameTypeClosure()
1423-
c.flags.incl {IgnoreTupleFields, PickyCAliases, PickyBackendAliases}
1423+
c.flags.incl {IgnoreTupleFields, IgnoreRangeShallow, PickyCAliases, PickyBackendAliases}
14241424
c.cmp = dcEqIgnoreDistinct
14251425
result = sameTypeAux(x, y, c)
14261426

tests/ccgbugs/taddrconvs.nim

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
discard """
2+
targets: "c cpp"
3+
matrix: "--mm:refc; --mm:orc"
4+
"""
5+
6+
{.emit:"""
7+
void foo(unsigned long long* x)
8+
{
9+
}
10+
""".}
11+
12+
block:
13+
proc foo(x: var culonglong) {.importc: "foo", nodecl.}
14+
15+
proc main(x: var uint64) =
16+
foo(culonglong x)
17+
18+
var u = uint64(12)
19+
main(u)
20+
21+
block:
22+
proc foo(x: var culonglong) {.importc: "foo", nodecl.}
23+
24+
proc main() =
25+
var m = uint64(12)
26+
foo(culonglong(m))
27+
main()

0 commit comments

Comments
 (0)