summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-04-20 22:15:25 +0200
committerAraq <rumpf_a@web.de>2014-04-20 22:15:25 +0200
commit407515993336f5e686f2c93c0fd05d189a5cad3c (patch)
tree77420f6ea342f1ef49a75f55794397a339bcfd7d
parentda7d6c844604e443c47fe0317e579d9d61e5fa3d (diff)
downloadNim-407515993336f5e686f2c93c0fd05d189a5cad3c.tar.gz
reintroduce thread analysis but disable it for backwards compatibility
-rw-r--r--compiler/commands.nim2
-rw-r--r--compiler/lowerings.nim7
-rw-r--r--compiler/options.nim1
-rw-r--r--compiler/pragmas.nim11
-rw-r--r--compiler/sempass2.nim11
-rw-r--r--doc/advopt.txt1
-rw-r--r--lib/pure/osproc.nim10
7 files changed, 26 insertions, 17 deletions
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 53e05aea1..8339219ed 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -168,6 +168,7 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
   of "forcebuild", "f": result = contains(gGlobalOptions, optForceFullMake)
   of "warnings", "w": result = contains(gOptions, optWarns)
   of "hints": result = contains(gOptions, optHints)
+  of "threadanalysis": result = contains(gGlobalOptions, optThreadAnalysis)
   of "stacktrace": result = contains(gOptions, optStackTrace)
   of "linetrace": result = contains(gOptions, optLineTrace)
   of "debugger": result = contains(gOptions, optEndb)
@@ -329,6 +330,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
   of "warning": processSpecificNote(arg, wWarning, pass, info)
   of "hint": processSpecificNote(arg, wHint, pass, info)
   of "hints": processOnOffSwitch({optHints}, arg, pass, info)
+  of "threadanalysis": processOnOffSwitchG({optThreadAnalysis}, arg, pass, info)
   of "stacktrace": processOnOffSwitch({optStackTrace}, arg, pass, info)
   of "linetrace": processOnOffSwitch({optLineTrace}, arg, pass, info)
   of "debugger": 
diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim
index efa3109c5..1b9e5fe0f 100644
--- a/compiler/lowerings.nim
+++ b/compiler/lowerings.nim
@@ -12,7 +12,7 @@
 const
   genPrefix* = ":tmp"         # prefix for generated names
 
-import ast, astalgo, types, idents, magicsys, msgs
+import ast, astalgo, types, idents, magicsys, msgs, options
 
 proc newTupleAccess*(tup: PNode, i: int): PNode =
   result = newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(
@@ -151,8 +151,9 @@ proc wrapProcForSpawn*(owner: PSym; n: PNode): PNode =
   if n.kind notin nkCallKinds or not n.typ.isEmptyType:
     localError(n.info, "'spawn' takes a call expression of type void")
     return
-  if {tfThread, tfNoSideEffect} * n[0].typ.flags == {}:
-    localError(n.info, "'spawn' takes a GC safe call expression")
+  if optThreadAnalysis in gGlobalOptions:
+    if {tfThread, tfNoSideEffect} * n[0].typ.flags == {}:
+      localError(n.info, "'spawn' takes a GC safe call expression")
   var
     threadParam = newSym(skParam, getIdent"thread", owner, n.info)
     argsParam = newSym(skParam, getIdent"args", owner, n.info)
diff --git a/compiler/options.nim b/compiler/options.nim
index 211eee360..36d343d1b 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -60,6 +60,7 @@ type                          # please make sure we have under 32 options
     optContext,               # ideTools: 'context'
     optDef,                   # ideTools: 'def'
     optUsages,                # ideTools: 'usages'
+    optThreadAnalysis,        # thread analysis pass
     optTaintMode,             # taint mode turned on
     optTlsEmulation,          # thread var emulation turned on
     optGenIndex               # generate index file for documentation;
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 4cc9c4197..db9fe7cbe 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -1,7 +1,7 @@
 #
 #
 #           The Nimrod Compiler
-#        (c) Copyright 2012 Andreas Rumpf
+#        (c) Copyright 2014 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -689,10 +689,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
           incl(sym.flags, sfProcvar)
           if sym.typ != nil: incl(sym.typ.flags, tfThread)
         of wGcSafe:
-          noVal(it)
-          if sym.kind != skType: incl(sym.flags, sfThread)
-          if sym.typ != nil: incl(sym.typ.flags, tfGcSafe)
-          else: invalidPragma(it)
+          if optThreadAnalysis in gGlobalOptions:
+            noVal(it)
+            if sym.kind != skType: incl(sym.flags, sfThread)
+            if sym.typ != nil: incl(sym.typ.flags, tfGcSafe)
+            else: invalidPragma(it)
         of wPacked:
           noVal(it)
           if sym.typ == nil: invalidPragma(it)
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index f8685a5c8..6235fb76a 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -705,11 +705,12 @@ proc trackProc*(s: PSym, body: PNode) =
       checkRaisesSpec(usesSpec, t.uses,
         "uses an unlisted global variable: ", hints=on, symbolPredicate)
       effects.sons[usesEffects] = usesSpec
-  if sfThread in s.flags and t.gcUnsafe:
-    localError(s.info, warnGcUnsafe2, s.name.s)
-    #localError(s.info, "'$1' is not GC-safe" % s.name.s)
-  if not t.gcUnsafe: s.typ.flags.incl tfGcSafe
-  
+  if optThreadAnalysis in gGlobalOptions:
+    if sfThread in s.flags and t.gcUnsafe:
+      localError(s.info, warnGcUnsafe2, s.name.s)
+      #localError(s.info, "'$1' is not GC-safe" % s.name.s)
+    if not t.gcUnsafe: s.typ.flags.incl tfGcSafe
+
 proc trackTopLevelStmt*(module: PSym; n: PNode) =
   if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef,
                 nkTypeSection, nkConverterDef, nkMethodDef, nkIteratorDef}:
diff --git a/doc/advopt.txt b/doc/advopt.txt
index 143c465fa..f5ff90791 100644
--- a/doc/advopt.txt
+++ b/doc/advopt.txt
@@ -63,6 +63,7 @@ Advanced options:
   --lineDir:on|off          generation of #line directive on|off
   --embedsrc                embeds the original source code as comments
                             in the generated output
+  --threadanalysis:on|off   turn thread analysis on|off
   --tlsEmulation:on|off     turn thread local storage emulation on|off
   --taintMode:on|off        turn taint mode on|off
   --symbolFiles:on|off      turn symbol files on|off (experimental)
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index ed83507d4..6e250f9d5 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -615,11 +615,13 @@ elif not defined(useNimRtl):
     optionPoStdErrToStdOut: bool
 
   when not defined(useFork):
-    proc startProcessAuxSpawn(data: TStartProcessData): TPid {.tags: [FExecIO, FReadEnv].}
-  proc startProcessAuxFork(data: TStartProcessData): TPid {.tags: [FExecIO, FReadEnv].}
+    proc startProcessAuxSpawn(data: TStartProcessData): TPid {.
+      tags: [FExecIO, FReadEnv], gcsafe.}
+  proc startProcessAuxFork(data: TStartProcessData): TPid {.
+    tags: [FExecIO, FReadEnv], gcsafe.}
   {.push stacktrace: off, profiler: off.}
   proc startProcessAfterFork(data: ptr TStartProcessData) {.
-    tags: [FExecIO, FReadEnv], cdecl.}
+    tags: [FExecIO, FReadEnv], cdecl, gcsafe.}
   {.pop.}
 
   proc startProcess(command: string,
@@ -946,7 +948,7 @@ elif not defined(useNimRtl):
 proc execCmdEx*(command: string, options: set[TProcessOption] = {
                 poStdErrToStdOut, poUsePath}): tuple[
                 output: TaintedString,
-                exitCode: int] {.tags: [FExecIO, FReadIO].} =
+                exitCode: int] {.tags: [FExecIO, FReadIO], gcsafe.} =
   ## a convenience proc that runs the `command`, grabs all its output and
   ## exit code and returns both.
   var p = startCmd(command, options)