diff --git a/changelog.md b/changelog.md index 60e5988f175f0..655da5feb83a7 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 10dda0ca9a929..216f6ba681e42 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 8c1c3d8a5512c..eb750864a5ae9 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 dc0197f14c467..6f3be4c895830 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.}