summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2020-03-19 09:56:30 +0100
committerGitHub <noreply@github.com>2020-03-19 09:56:30 +0100
commitba6e7c636574b5c7add118daa7df6e4331f23fe1 (patch)
tree272c08d505da18a9888a8471572fcd03ba1d8403
parentb5c9881a3056bd427ac1df2960d5497327fba946 (diff)
downloadNim-ba6e7c636574b5c7add118daa7df6e4331f23fe1.tar.gz
added a switch -d:nimEmulateOverflowChecks for broken or old GCC versions (#13692)
-rw-r--r--changelog.md6
-rw-r--r--compiler/cgen.nim8
-rw-r--r--lib/nimbase.h2
-rw-r--r--lib/system/integerops.nim2
4 files changed, 13 insertions, 5 deletions
diff --git a/changelog.md b/changelog.md
index 60e5988f1..655da5feb 100644
--- a/changelog.md
+++ b/changelog.md
@@ -3,6 +3,12 @@
 
 ## Changes affecting backwards compatibility
 
+- The Nim compiler now implements a faster way to detect overflows based
+  on GCC's `__builtin_sadd_overflow` family of functions. (Clang also
+  supports these). Some versions of GCC lack this feature and unfortunately
+  we cannot detect this case reliably. So if you get compilation errors like
+  "undefined reference to '__builtin_saddll_overflow'" compile your programs
+  with `-d:nimEmulateOverflowChecks`.
 
 
 ### Breaking changes in the standard library
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 10dda0ca9..216f6ba68 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -1234,13 +1234,15 @@ proc genVarPrototype(m: BModule, n: PNode) =
         "\t$1 = ($2*)hcrGetGlobal($3, \"$1\");$n", [sym.loc.r,
         getTypeDesc(m, sym.loc.t), getModuleDllPath(m, sym)])
 
-proc addIntTypes(result: var Rope; conf: ConfigRef) {.inline.} =
+proc addNimDefines(result: var Rope; conf: ConfigRef) {.inline.} =
   result.addf("#define NIM_INTBITS $1\L", [
     platform.CPU[conf.target.targetCPU].intSize.rope])
   if conf.cppCustomNamespace.len > 0:
     result.add("#define USE_NIM_NAMESPACE ")
     result.add(conf.cppCustomNamespace)
     result.add("\L")
+  if conf.isDefined("nimEmulateOverflowChecks"):
+    result.add("#define NIM_EmulateOverflowChecks\L")
 
 proc getCopyright(conf: ConfigRef; cfile: Cfile): Rope =
   if optCompileOnly in conf.globalOptions:
@@ -1263,7 +1265,7 @@ proc getCopyright(conf: ConfigRef; cfile: Cfile): Rope =
 proc getFileHeader(conf: ConfigRef; cfile: Cfile): Rope =
   result = getCopyright(conf, cfile)
   if conf.hcrOn: result.add("#define NIM_HOT_CODE_RELOADING\L")
-  addIntTypes(result, conf)
+  addNimDefines(result, conf)
 
 proc getSomeNameForModule(m: PSym): Rope =
   assert m.kind == skModule
@@ -1825,7 +1827,7 @@ proc writeHeader(m: BModule) =
 
   var guard = "__$1__" % [m.filename.splitFile.name.rope]
   result.addf("#ifndef $1$n#define $1$n", [guard])
-  addIntTypes(result, m.config)
+  addNimDefines(result, m.config)
   generateHeaders(m)
 
   generateThreadLocalStorage(m)
diff --git a/lib/nimbase.h b/lib/nimbase.h
index 8c1c3d8a5..eb750864a 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -549,7 +549,7 @@ typedef int Nim_and_C_compiler_disagree_on_target_architecture[sizeof(NI) == siz
 #define nimModInt(a, b, res) (((*res) = (a) % (b)), 0)
 #define nimModInt64(a, b, res) (((*res) = (a) % (b)), 0)
 
-#if !defined(_MSC_VER)
+#if !defined(_MSC_VER) && !defined(NIM_EmulateOverflowChecks)
   /* these exist because we cannot have .compilerProcs that are importc'ed
     by a different name */
 
diff --git a/lib/system/integerops.nim b/lib/system/integerops.nim
index dc0197f14..6f3be4c89 100644
--- a/lib/system/integerops.nim
+++ b/lib/system/integerops.nim
@@ -19,7 +19,7 @@ proc raiseDivByZero {.compilerproc, noinline.} =
 
 {.pragma: nimbaseH, importc, nodecl, noSideEffect, compilerproc.}
 
-when defined(gcc) or defined(clang):
+when (defined(gcc) or defined(clang)) and not defined(nimEmulateOverflowChecks):
   # take the #define from nimbase.h
 
   proc nimAddInt(a, b: int, res: ptr int): bool {.nimbaseH.}