summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/astalgo.nim4
-rw-r--r--compiler/semmagic.nim26
-rw-r--r--compiler/sempass2.nim4
-rw-r--r--tests/arc/t14383.nim14
4 files changed, 36 insertions, 12 deletions
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim
index d9cd5ade1..832f8819a 100644
--- a/compiler/astalgo.nim
+++ b/compiler/astalgo.nim
@@ -110,14 +110,14 @@ proc iiTablePut*(t: var TIITable, key, val: int)
 
 # implementation
 
-proc skipConvAndClosure*(n: PNode): PNode =
+proc skipConvCastAndClosure*(n: PNode): PNode =
   result = n
   while true:
     case result.kind
     of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64,
        nkClosure:
       result = result[0]
-    of nkHiddenStdConv, nkHiddenSubConv, nkConv:
+    of nkHiddenStdConv, nkHiddenSubConv, nkConv, nkCast:
       result = result[1]
     else: break
 
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index 5e6b4dbe2..3368bcfbf 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -527,14 +527,24 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
     if n[^1].kind == nkSym and n[^1].sym.kind notin {skProc, skFunc}:
       localError(c.config, n.info, "finalizer must be a direct reference to a proc")
     elif optTinyRtti in c.config.globalOptions:
-      let fin = if n[^1].kind in {nkLambda, nkDo}: n[^1][namePos].sym
-                else: n[^1].sym
-      # check if we converted this finalizer into a destructor already:
-      let t = whereToBindTypeHook(c, fin.typ[1].skipTypes(abstractInst+{tyRef}))
-      if t != nil and t.attachedOps[attachedDestructor] != nil and t.attachedOps[attachedDestructor].owner == fin:
-        discard "already turned this one into a finalizer"
-      else:
-        bindTypeHook(c, turnFinalizerIntoDestructor(c, fin, n.info), n, attachedDestructor)
+      let nfin = skipConvCastAndClosure(n[^1])
+      let fin = case nfin.kind 
+        of nkSym: nfin.sym
+        of nkLambda, nkDo: nfin[namePos].sym
+        else: 
+          localError(c.config, n.info, "finalizer must be a direct reference to a proc")
+          nil
+      if fin != nil:
+        if fin.kind notin {skProc, skFunc}:
+          # calling convention is checked in codegen
+          localError(c.config, n.info, "finalizer must be a direct reference to a proc")
+
+        # check if we converted this finalizer into a destructor already:
+        let t = whereToBindTypeHook(c, fin.typ[1].skipTypes(abstractInst+{tyRef}))
+        if t != nil and t.attachedOps[attachedDestructor] != nil and t.attachedOps[attachedDestructor].owner == fin:
+          discard "already turned this one into a finalizer"
+        else:
+          bindTypeHook(c, turnFinalizerIntoDestructor(c, fin, n.info), n, attachedDestructor)
     result = n
   of mDestroy:
     result = n
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index 92a896a38..39ba1b307 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -510,7 +510,7 @@ proc procVarCheck(n: PNode; conf: ConfigRef) =
 proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) =
   let n = n.skipConv
   if paramType.isNil or paramType.kind != tyTypeDesc:
-    procVarCheck skipConvAndClosure(n), tracked.config
+    procVarCheck skipConvCastAndClosure(n), tracked.config
   #elif n.kind in nkSymChoices:
   #  echo "came here"
   let paramType = paramType.skipTypesOrNil(abstractInst)
@@ -556,7 +556,7 @@ proc isTrival(caller: PNode): bool {.inline.} =
   result = caller.kind == nkSym and caller.sym.magic in {mEqProc, mIsNil, mMove, mWasMoved, mSwap}
 
 proc trackOperandForIndirectCall(tracked: PEffects, n: PNode, paramType: PType; caller: PNode) =
-  let a = skipConvAndClosure(n)
+  let a = skipConvCastAndClosure(n)
   let op = a.typ
   # assume indirect calls are taken here:
   if op != nil and op.kind == tyProc and n.skipConv.kind != nkNilLit and not isTrival(caller):
diff --git a/tests/arc/t14383.nim b/tests/arc/t14383.nim
index f112a1a6c..834c50def 100644
--- a/tests/arc/t14383.nim
+++ b/tests/arc/t14383.nim
@@ -34,3 +34,17 @@ echo x
 
 import std/os
 discard getFileInfo(".")
+
+
+#------------------------------------------------------------------------------
+# Issue #15707
+#------------------------------------------------------------------------------
+
+type
+  JVMObject = ref object
+proc freeJVMObject(o: JVMObject) =
+  discard
+proc fromJObject(T: typedesc[JVMObject]): T =
+  result.new(cast[proc(r: T) {.nimcall.}](freeJVMObject))
+
+discard JVMObject.fromJObject()
\ No newline at end of file