Merge branch 'devel' into pr_exportc_error

This commit is contained in:
ringabout
2026-03-31 12:50:38 +08:00
committed by GitHub
15 changed files with 205 additions and 21 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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])

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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':

View File

@@ -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]

View File

@@ -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

View File

@@ -219,3 +219,6 @@ block: # bug #19531
x.cb()
y.cb()
block:
proc r(_: typedesc, _: static uint | static int) = discard; r(uint, 0)

View File

@@ -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]

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -143,3 +143,7 @@ proc discardableCall(cmd: string): int {.discardable.} =
result = 123
discardableCall "echo hi"
block:
let a = "abc"
doAssert @a == @['a', 'b', 'c']