mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-14 19:45:55 +00:00
Merge branch 'devel' into pr_exportc_error
This commit is contained in:
@@ -309,7 +309,7 @@ proc addAbiCheck(m: BModule; t: PType, name: Rope) =
|
||||
|
||||
|
||||
proc fillResult(conf: ConfigRef; param: PNode, proctype: PType) =
|
||||
ensureMutable param.sym
|
||||
backendEnsureMutable param.sym
|
||||
fillLoc(param.sym.locImpl, locParam, param, "Result",
|
||||
OnStack)
|
||||
let t = param.sym.typ
|
||||
@@ -542,7 +542,7 @@ proc genMemberProcParams(m: BModule; prc: PSym, superCall, rettype, name, params
|
||||
var types, names, args: seq[string] = @[]
|
||||
if not isCtor:
|
||||
var this = t.n[1].sym
|
||||
ensureMutable this
|
||||
backendEnsureMutable this
|
||||
fillParamName(m, this)
|
||||
fillLoc(this.locImpl, locParam, t.n[1],
|
||||
this.paramStorageLoc)
|
||||
@@ -564,7 +564,7 @@ proc genMemberProcParams(m: BModule; prc: PSym, superCall, rettype, name, params
|
||||
else:
|
||||
descKind = dkRefParam
|
||||
var typ, name: string
|
||||
ensureMutable param
|
||||
backendEnsureMutable param
|
||||
fillParamName(m, param)
|
||||
fillLoc(param.locImpl, locParam, t.n[i],
|
||||
param.paramStorageLoc)
|
||||
@@ -1183,7 +1183,7 @@ proc genMemberProcHeader(m: BModule; prc: PSym; result: var Builder; asPtr: bool
|
||||
let isCtor = sfConstructor in prc.flags
|
||||
var check = initIntSet()
|
||||
fillBackendName(m, prc)
|
||||
ensureMutable prc
|
||||
backendEnsureMutable prc
|
||||
fillLoc(prc.locImpl, locProc, prc.ast[namePos], OnUnknown)
|
||||
var memberOp = "#." #only virtual
|
||||
var typ: PType
|
||||
|
||||
@@ -951,7 +951,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
expectArg(conf, switch, arg, pass, info)
|
||||
var value: int = 10_000_000
|
||||
discard parseSaturatedNatural(arg, value)
|
||||
if not value > 0: localError(conf, info, "maxLoopIterationsVM must be a positive integer greater than zero")
|
||||
if value <= 0: localError(conf, info, "maxLoopIterationsVM must be a positive integer greater than zero")
|
||||
conf.maxLoopIterationsVM = value
|
||||
of "maxcalldepthvm":
|
||||
expectArg(conf, switch, arg, pass, info)
|
||||
|
||||
@@ -148,7 +148,7 @@ proc cmpDecimalsIgnoreCase(a, b: string): int =
|
||||
limitB = iB
|
||||
while limitA < aLen and isDigit(a[limitA]): inc limitA
|
||||
while limitB < bLen and isDigit(b[limitB]): inc limitB
|
||||
var pos = max(limitA-iA, limitB-iA)
|
||||
var pos = max(limitA-iA, limitB-iB)
|
||||
while pos > 0:
|
||||
if limitA-pos < iA: # digit in `a` is 0 effectively
|
||||
result = ord('0') - ord(b[limitB-pos])
|
||||
|
||||
@@ -44,14 +44,16 @@ proc loadModuleDependencies(g: ModuleGraph; mainFileIdx: FileIndex): seq[Precomp
|
||||
let suffix = stack.pop()
|
||||
|
||||
if not visited.containsOrIncl(suffix.string):
|
||||
let nifFile = toGeneratedFile(g.config, AbsoluteFile(suffix.string), ".nif")
|
||||
let fileIdx = msgs.fileInfoIdx(g.config, nifFile)
|
||||
var isKnownFile = false
|
||||
let fileIdx = g.config.registerNifSuffix(suffix.string, isKnownFile)
|
||||
let precomp = moduleFromNifFile(g, fileIdx, {LoadFullAst})
|
||||
if precomp.module != nil:
|
||||
result.add precomp
|
||||
for dep in precomp.deps:
|
||||
if not visited.contains(dep.string):
|
||||
stack.add dep
|
||||
else:
|
||||
assert false, "Recompiling module is not implemented."
|
||||
|
||||
if mainModule.module != nil:
|
||||
result.add mainModule
|
||||
|
||||
@@ -2234,6 +2234,9 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
result = semAnyRef(c, n, tyPtr, prev)
|
||||
elif op.id == ord(wRef):
|
||||
result = semAnyRef(c, n, tyRef, prev)
|
||||
elif op.id == ord(wStatic):
|
||||
checkSonsLen(n, 2, c.config)
|
||||
result = semStaticType(c, n[1], prev)
|
||||
elif op.id == ord(wType):
|
||||
checkSonsLen(n, 2, c.config)
|
||||
result = semTypeOf(c, n[1], prev)
|
||||
|
||||
@@ -99,12 +99,13 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||
if isInlineIterator(typ) and kind in {skVar, skLet, skConst, skParam, skResult}:
|
||||
# only closure iterators may be assigned to anything.
|
||||
result = t
|
||||
let f = if kind in {skProc, skFunc}: flags+{taNoUntyped} else: flags
|
||||
let innerFlags = flags - {taObjField, taTupField, taIsOpenArray}
|
||||
let f = if kind in {skProc, skFunc}: innerFlags+{taNoUntyped} else: innerFlags
|
||||
for _, a in t.paramTypes:
|
||||
if result != nil: break
|
||||
result = typeAllowedAux(marker, a, skParam, c, f-{taIsOpenArray})
|
||||
result = typeAllowedAux(marker, a, skParam, c, f)
|
||||
if result.isNil and t.returnType != nil:
|
||||
result = typeAllowedAux(marker, t.returnType, skResult, c, flags)
|
||||
result = typeAllowedAux(marker, t.returnType, skResult, c, innerFlags)
|
||||
of tyTypeDesc:
|
||||
if kind in {skVar, skLet, skConst} and taProcContextIsNotMacro in flags:
|
||||
result = t
|
||||
|
||||
@@ -556,7 +556,7 @@ proc replace(s: string): string =
|
||||
while i < s.len():
|
||||
if s[i] == '\\':
|
||||
d.add(r"\\")
|
||||
elif s[i] == '\c' and s[i+1] == '\l':
|
||||
elif s[i] == '\c' and i+1 < s.len() and s[i+1] == '\l':
|
||||
d.add(r"\c\l")
|
||||
inc(i)
|
||||
elif s[i] == '\c':
|
||||
|
||||
@@ -1469,7 +1469,7 @@ when defined(nimHasTopDownInference):
|
||||
## This is not as efficient as turning a fixed length array into a sequence
|
||||
## as it always copies every element of `a`.
|
||||
let sz = a.len
|
||||
when supportsCopyMem(T) and not defined(js):
|
||||
when supportsCopyMem(T) and not defined(js) and not defined(nimscript):
|
||||
result = newSeqUninit[T](sz)
|
||||
when nimvm:
|
||||
for i in 0..sz-1: result[i] = a[i]
|
||||
|
||||
@@ -306,15 +306,15 @@ proc `mod`*(x, y: uint32): uint32 {.magic: "ModU", noSideEffect.}
|
||||
proc `mod`*(x, y: uint64): uint64 {.magic: "ModU", noSideEffect.}
|
||||
|
||||
proc `+=`*[T: SomeInteger](x: var T, y: T) {.
|
||||
magic: "Inc", noSideEffect.}
|
||||
magic: "Inc", noSideEffect, systemRaisesDefect.}
|
||||
## Increments an integer.
|
||||
|
||||
proc `-=`*[T: SomeInteger](x: var T, y: T) {.
|
||||
magic: "Dec", noSideEffect.}
|
||||
magic: "Dec", noSideEffect, systemRaisesDefect.}
|
||||
## Decrements an integer.
|
||||
|
||||
proc `*=`*[T: SomeInteger](x: var T, y: T) {.
|
||||
inline, noSideEffect.} =
|
||||
inline, noSideEffect, systemRaisesDefect.} =
|
||||
## Binary `*=` operator for integers.
|
||||
x = x * y
|
||||
|
||||
@@ -339,20 +339,22 @@ proc `+=`*[T: float|float32|float64] (x: var T, y: T) {.
|
||||
x = x + y
|
||||
|
||||
proc `-=`*[T: float|float32|float64] (x: var T, y: T) {.
|
||||
inline, noSideEffect.} =
|
||||
inline, noSideEffect, systemRaisesDefect.} =
|
||||
## Decrements in place a floating point number.
|
||||
x = x - y
|
||||
|
||||
proc `*=`*[T: float|float32|float64] (x: var T, y: T) {.
|
||||
inline, noSideEffect.} =
|
||||
inline, noSideEffect, systemRaisesDefect.} =
|
||||
## Multiplies in place a floating point number.
|
||||
x = x * y
|
||||
|
||||
proc `/=`*(x: var float64, y: float64) {.inline, noSideEffect.} =
|
||||
proc `/=`*(x: var float64, y: float64) {.
|
||||
inline, noSideEffect, systemRaisesDefect.} =
|
||||
## Divides in place a floating point number.
|
||||
x = x / y
|
||||
|
||||
proc `/=`*[T: float|float32](x: var T, y: T) {.inline, noSideEffect.} =
|
||||
proc `/=`*[T: float|float32](x: var T, y: T) {.
|
||||
inline, noSideEffect, systemRaisesDefect.} =
|
||||
## Divides in place a floating point number.
|
||||
x = x / y
|
||||
|
||||
|
||||
@@ -219,3 +219,6 @@ block: # bug #19531
|
||||
x.cb()
|
||||
y.cb()
|
||||
|
||||
|
||||
block:
|
||||
proc r(_: typedesc, _: static uint | static int) = discard; r(uint, 0)
|
||||
|
||||
@@ -4,6 +4,8 @@ discard """
|
||||
5
|
||||
3
|
||||
2
|
||||
1.0
|
||||
2.0
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -42,4 +44,26 @@ proc divmod(a, b: int): (int, int) =
|
||||
|
||||
let (q, r) = divmod(17, 5)
|
||||
echo q
|
||||
echo r
|
||||
echo r
|
||||
|
||||
|
||||
# Shallow object with seq (trigger GC interaction)
|
||||
type
|
||||
Matrix = object
|
||||
rows, cols: int
|
||||
data: seq[float]
|
||||
|
||||
proc newMatrix(r, c: int): Matrix =
|
||||
Matrix(rows: r, cols: c, data: newSeq[float](r * c))
|
||||
|
||||
proc `[]`(m: Matrix, r, c: int): float =
|
||||
m.data[r * m.cols + c]
|
||||
|
||||
proc `[]=`(m: var Matrix, r, c: int, v: float) =
|
||||
m.data[r * m.cols + c] = v
|
||||
|
||||
var m = newMatrix(2, 2)
|
||||
m[0, 0] = 1.0
|
||||
m[1, 1] = 2.0
|
||||
echo m[0, 0]
|
||||
echo m[1, 1]
|
||||
|
||||
@@ -23,3 +23,25 @@ block:
|
||||
doAssert x(a) == 1
|
||||
doAssert y(a) == 1
|
||||
|
||||
|
||||
import std/tables
|
||||
|
||||
block:
|
||||
type
|
||||
R = proc(): lent O {.nimcall.}
|
||||
F = object
|
||||
schema: R
|
||||
O = object
|
||||
fields: Table[string, F]
|
||||
|
||||
func f(o: O, key: string): R =
|
||||
if key in o.fields: o.fields[key].schema
|
||||
else: nil
|
||||
|
||||
block:
|
||||
type
|
||||
R = proc(): lent O
|
||||
O = object
|
||||
r: R
|
||||
|
||||
func f(o: O): int = 42
|
||||
|
||||
@@ -64,3 +64,120 @@ block: # bug #24683
|
||||
cast[ptr int](addr x)[] = 10
|
||||
|
||||
doAssert x == @[1, 2, 3, 4, 45, 56, 67, 999, 88, 777]
|
||||
|
||||
when not defined(js):
|
||||
block:
|
||||
var x = high int
|
||||
var result = x
|
||||
|
||||
# assert that multiplying highest int by highest int overflows
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
x *= x
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
result *= x
|
||||
|
||||
# overflow via compound assignment on int
|
||||
var a = high(int)
|
||||
doAssertRaises(OverflowDefect):
|
||||
a += 1
|
||||
|
||||
var b = low(int)
|
||||
doAssertRaises(OverflowDefect):
|
||||
b -= 1
|
||||
|
||||
var c = high(int)
|
||||
doAssertRaises(OverflowDefect):
|
||||
c *= 2
|
||||
|
||||
# add smaller signed types too
|
||||
var a8 = high(int8)
|
||||
doAssertRaises(OverflowDefect):
|
||||
a8 += 1
|
||||
|
||||
var b8 = low(int8)
|
||||
doAssertRaises(OverflowDefect):
|
||||
b8 -= 1
|
||||
|
||||
var c8 = high(int8)
|
||||
doAssertRaises(OverflowDefect):
|
||||
c8 *= 2
|
||||
|
||||
var a16 = high(int16)
|
||||
doAssertRaises(OverflowDefect):
|
||||
a16 += 1
|
||||
|
||||
var b16 = low(int16)
|
||||
doAssertRaises(OverflowDefect):
|
||||
b16 -= 1
|
||||
|
||||
# arithmetic operations that can overflow (non-compound direct ops)
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard high(int) + 1
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard low(int) - 1
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard high(int) * 2
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard low(int) div -1
|
||||
|
||||
# int8 overflow for signed operations
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard high(int8) + 1'i8
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard low(int8) - 1'i8
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard high(int8) * 2'i8
|
||||
|
||||
# enum overflow, from arithmetics.succ/pred
|
||||
type E = enum eA, eB
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard eB.succ
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard eA.pred
|
||||
|
||||
# floating-point compound divide should produce inf (not raise by defect)
|
||||
var f = 1.0
|
||||
f /= 0.0
|
||||
# 1.0/0.0 is inf, check not finite
|
||||
#doAssert not f.isFinite # `isFinite` not in this context, but avoid crash
|
||||
# simple check ensures it mutated to a very large value
|
||||
# (in Nim, `inf` is represented as 1e300*1e300; this compares as true)
|
||||
doAssert f == 1.0 / 0.0
|
||||
|
||||
# Additional overflow cases across various integer widths
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard high(int32) + 1'i32
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard low(int32) - 1'i32
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard high(int64) + 1'i64
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard low(int64) - 1'i64
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard -low(int64)
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard abs(low(int8))
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard high(int32) * 2'i32
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard high(int64) * 2'i64
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard low(int32) div -1'i32
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard low(int64) div -1'i64
|
||||
|
||||
@@ -130,3 +130,9 @@ block:
|
||||
doAssert dict.getSectionValue(section4, "can_values_be_as_well") == "True"
|
||||
doAssert dict.getSectionValue(section4, "does_that_mean_anything_special") == "False"
|
||||
doAssert dict.getSectionValue(section4, "purpose") == "formatting for readability"
|
||||
|
||||
block: # bug #25674
|
||||
var dict = newConfig()
|
||||
dict.setSectionKey("", "key", "value\c")
|
||||
var s = newStringStream()
|
||||
dict.writeConfig(s)
|
||||
|
||||
@@ -143,3 +143,7 @@ proc discardableCall(cmd: string): int {.discardable.} =
|
||||
result = 123
|
||||
|
||||
discardableCall "echo hi"
|
||||
|
||||
block:
|
||||
let a = "abc"
|
||||
doAssert @a == @['a', 'b', 'c']
|
||||
|
||||
Reference in New Issue
Block a user