summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorTimothee Cour <timothee.cour2@gmail.com>2020-05-12 07:19:03 -0700
committerGitHub <noreply@github.com>2020-05-12 16:19:03 +0200
commitde74362213baeb28d52c05c71cd9b8389ae69060 (patch)
treef59b8f3ef24f45a78e9a5b0a7919ff1fedd3cbee
parent06dfd316127fb2ec05ff69942abd1e279156ac5c (diff)
downloadNim-de74362213baeb28d52c05c71cd9b8389ae69060.tar.gz
fix #14314 do not analyze importc procs for effects (#14319)
-rw-r--r--compiler/lineinfos.nim4
-rw-r--r--compiler/sempass2.nim7
-rw-r--r--tests/misc/mimportc.nim26
-rw-r--r--tests/trunner.nim14
4 files changed, 44 insertions, 7 deletions
diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim
index eea55defc..d6c863842 100644
--- a/compiler/lineinfos.nim
+++ b/compiler/lineinfos.nim
@@ -23,7 +23,7 @@ type
     errGeneralParseError,
     errNewSectionExpected,
     errInvalidDirectiveX,
-    errProveInit,
+    errProveInit, # deadcode
     errGenerated,
     errUser,
     warnCannotOpenFile,
@@ -66,7 +66,7 @@ const
     errGeneralParseError: "general parse error",
     errNewSectionExpected: "new section expected",
     errInvalidDirectiveX: "invalid directive: '$1'",
-    errProveInit: "Cannot prove that '$1' is initialized.",
+    errProveInit: "Cannot prove that '$1' is initialized.",  # deadcode
     errGenerated: "$1",
     errUser: "$1",
     warnCannotOpenFile: "cannot open '$1'",
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index a7b01a75e..862123eab 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -1151,12 +1151,17 @@ proc initEffects(g: ModuleGraph; effects: PNode; s: PSym; t: var TEffects; c: PC
   t.config = g.config
   t.c = c
 
+proc hasRealBody(s: PSym): bool =
+  ## also handles importc procs with runnableExamples, which requires `=`,
+  ## which is not a real implementation, refs #14314
+  result = {sfForward, sfImportc} * s.flags == {}
+
 proc trackProc*(c: PContext; s: PSym, body: PNode) =
   let g = c.graph
   var effects = s.typ.n[0]
   if effects.kind != nkEffectList: return
   # effects already computed?
-  if sfForward in s.flags: return
+  if not s.hasRealBody: return
   if effects.len == effectListLen: return
 
   var t: TEffects
diff --git a/tests/misc/mimportc.nim b/tests/misc/mimportc.nim
new file mode 100644
index 000000000..602c6372d
--- /dev/null
+++ b/tests/misc/mimportc.nim
@@ -0,0 +1,26 @@
+#[
+this test will grow with more importc+importcpp tests; see driver in trunner.nim
+]#
+
+{.emit:"""
+struct A {
+  static int fun0(int a){
+    return a;
+  }
+  static int& fun1(int& a){
+    return a;
+  }
+};
+""".}
+
+proc fun0*(a: cint): int {.importcpp:"A::$1(@)".}
+proc fun1*(a: var cint): var int {.importcpp:"A::$1(@)".} =
+  ## some comment; this test is for #14314
+  runnableExamples: discard
+
+proc main()=
+  var a = 10.cint
+  doAssert fun0(a) == a
+  doAssert fun1(a).addr == a.addr
+  echo "witness"
+main()
diff --git a/tests/trunner.nim b/tests/trunner.nim
index e6a8a2077..bd74a8405 100644
--- a/tests/trunner.nim
+++ b/tests/trunner.nim
@@ -16,6 +16,10 @@ const mode =
   else: static: doAssert false
 
 const testsDir = currentSourcePath().parentDir
+const buildDir = testsDir.parentDir / "build"
+const nimcache = buildDir / "nimcacheTrunner"
+  # `querySetting(nimcacheDir)` would also be possible, but we thus
+  # avoid stomping on other parallel tests
 
 proc runCmd(file, options = ""): auto =
   let fileabs = testsDir / file.unixToNativePath
@@ -108,10 +112,6 @@ else: # don't run twice the same test
   block: # nim doc --backend:$backend --doccmd:$cmd
     # test for https://github.com/nim-lang/Nim/issues/13129
     # test for https://github.com/nim-lang/Nim/issues/13891
-    const buildDir = testsDir.parentDir / "build"
-    const nimcache = buildDir / "nimcacheTrunner"
-      # `querySetting(nimcacheDir)` would also be possible, but we thus
-      # avoid stomping on other parallel tests
     let file = testsDir / "nimdoc/m13129.nim"
     for backend in fmt"{mode} js".split:
       let cmd = fmt"{nim} doc -b:{backend} --nimcache:{nimcache} -d:m13129Foo1 --doccmd:'-d:m13129Foo2 --hints:off' --usenimcache --hints:off {file}"
@@ -122,3 +122,9 @@ else: # don't run twice the same test
     block: # mak sure --backend works with `nim r`
       let cmd = fmt"{nim} r --backend:{mode} --hints:off --nimcache:{nimcache} {file}"
       check execCmdEx(cmd) == ("ok3\n", 0)
+
+  block: # some importc tests
+    # issue #14314
+    let file = testsDir / "misc/mimportc.nim"
+    let cmd = fmt"{nim} r -b:cpp --hints:off --nimcache:{nimcache} --warningAsError:ProveInit {file}"
+    check execCmdEx(cmd) == ("witness\n", 0)