Converter bug fixes (#9700)

* Fixes #9698
* Fixes #9699
This commit is contained in:
cooldome
2018-11-15 12:14:48 +00:00
committed by Andreas Rumpf
parent 8c1083d3b7
commit c5c4da4f3c
4 changed files with 118 additions and 2 deletions

View File

@@ -138,6 +138,7 @@ proc effectProblem(f, a: PType; result: var string) =
proc renderNotLValue(n: PNode): string =
result = $n
let n = if n.kind == nkHiddenDeref: n[0] else: n
if n.kind == nkHiddenCallConv and n.len > 1:
result = $n[0] & "(" & result & ")"
elif n.kind in {nkHiddenStdConv, nkHiddenSubConv} and n.len == 2:
@@ -394,6 +395,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
args])
proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) =
let a = if a.kind == nkHiddenDeref: a[0] else: a
if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym:
let s = a.sons[0].sym
if s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty:

View File

@@ -640,6 +640,7 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
return
for i in countup(1, sonsLen(n) - 1):
let n = if n.kind == nkHiddenDeref: n[0] else: n
if n.sons[i].kind == nkHiddenCallConv:
# we need to recurse explicitly here as converters can create nested
# calls and then they wouldn't be analysed otherwise

View File

@@ -13,7 +13,7 @@
import
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees,
linter, lineinfos, modulegraphs
linter, lineinfos, lowerings, modulegraphs
when (defined(booting) or defined(nimsuggest)) and not defined(leanCompiler):
import docgen
@@ -1855,8 +1855,14 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
else:
param = copyTree(arg)
addSon(result, param)
if dest.kind in {tyVar, tyLent}:
dest.flags.incl tfVarIsPtr
result = newDeref(result)
inc(m.convMatches)
m.genericConverter = srca == isGeneric or destIsGeneric
if m.genericConverter == false:
m.genericConverter = srca == isGeneric or destIsGeneric
return result
proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType,

View File

@@ -0,0 +1,107 @@
discard """
file: "tconverter_unique_ptr.nim"
targets: "c cpp"
output: '''5
2.0 5
'''
"""
## Bugs 9698 and 9699
type
UniquePtr*[T] = object
## non copyable pointer to object T, exclusive ownership of the object is assumed
val: ptr T
MyLen* = distinct int
MySeq* = object
## Vectorized matrix
len: MyLen # scalar size
data: ptr UncheckedArray[float]
proc `$`(x: MyLen): string {.borrow.}
proc `=destroy`*(m: var MySeq) {.inline.} =
if m.data != nil:
deallocShared(m.data)
m.data = nil
proc `=`*(m: var MySeq, m2: MySeq) =
if m.data == m2.data: return
if m.data != nil:
`=destroy`(m)
m.len = m2.len
let bytes = m.len.int * sizeof(float)
if bytes > 0:
m.data = cast[ptr UncheckedArray[float]](allocShared(bytes))
copyMem(m.data, m2.data, bytes)
proc `=sink`*(m: var MySeq, m2: MySeq) {.inline.} =
if m.data != m2.data:
if m.data != nil:
`=destroy`(m)
m.len = m2.len
m.data = m2.data
proc len*(m: MySeq): MyLen {.inline.} = m.len
proc lenx*(m: var MySeq): MyLen {.inline.} = m.len
proc `[]`*(m: MySeq; i: MyLen): float {.inline.} =
m.data[i.int]
proc `[]=`*(m: var MySeq; i: MyLen, val: float) {.inline.} =
m.data[i.int] = val
proc setTo(s: var MySeq, val: float) =
for i in 0..<s.len.int:
s.data[i] = val
proc newMySeq*(size: int, initial_value = 0.0): MySeq =
result.len = size.MyLen
if size > 0:
result.data = cast[ptr UncheckedArray[float]](createShared(float, size))
result.setTo(initial_value)
converter literalToLen*(x: int{lit}): MyLen =
x.MyLen
#-------------------------------------------------------------
# Unique pointer implementation
#-------------------------------------------------------------
proc `=destroy`*[T](p: var UniquePtr[T]) =
if p.val != nil:
`=destroy`(p.val[])
dealloc(p.val)
p.val = nil
proc `=`*[T](dest: var UniquePtr[T], src: UniquePtr[T]) {.error.}
proc `=sink`*[T](dest: var UniquePtr[T], src: UniquePtr[T]) {.inline.} =
if dest.val != nil and dest.val != src.val:
`=destroy`(dest)
dest.val = src.val
proc newUniquePtr*[T](val: sink T): UniquePtr[T] =
result.val = cast[type(result.val)](alloc(sizeof(result.val[])))
reset(result.val[])
result.val[] = val
converter convertPtrToObj*[T](p: UniquePtr[T]): var T =
result = p.val[]
var pu = newUniquePtr(newMySeq(5, 1.0))
echo pu.len
pu[0] = 2.0
echo pu[0], " ", pu.lenx