diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2022-11-23 03:07:00 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-22 20:07:00 +0100 |
commit | 0448f30fd9c2e53084ee8b284f6fa24684661bc3 (patch) | |
tree | 04ce8580c319f10684ee390edd2aea85c13624ab | |
parent | 354eb2a86c75335c34cab8074b8b3532f09ecccf (diff) | |
download | Nim-0448f30fd9c2e53084ee8b284f6fa24684661bc3.tar.gz |
fixes #20026; marks system procs which can raise defects (#20864)
* marks system procs which can raise defects * add tests * add more systemRaisesDefect * add comment
-rw-r--r-- | compiler/ast.nim | 1 | ||||
-rw-r--r-- | compiler/ccgcalls.nim | 3 | ||||
-rw-r--r-- | compiler/condsyms.nim | 1 | ||||
-rw-r--r-- | compiler/pragmas.nim | 4 | ||||
-rw-r--r-- | compiler/wordrecg.nim | 2 | ||||
-rw-r--r-- | lib/system/indices.nim | 33 | ||||
-rw-r--r-- | tests/stdlib/tstring.nim | 1 |
7 files changed, 26 insertions, 19 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 22ad1aa27..9679c10c1 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -299,6 +299,7 @@ type sfInjectDestructors # whether the proc needs the 'injectdestructors' transformation sfNeverRaises # proc can never raise an exception, not even OverflowDefect # or out-of-memory + sfSystemRaisesDefect # proc in the system can raise defects sfUsedInFinallyOrExcept # symbol is used inside an 'except' or 'finally' sfSingleUsedTemp # For temporaries that we know will only be used once sfNoalias # 'noalias' annotation, means C's 'restrict' diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index a58f59c51..9993322fb 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -14,7 +14,8 @@ proc canRaiseDisp(p: BProc; n: PNode): bool = if n.kind == nkSym and {sfNeverRaises, sfImportc, sfCompilerProc} * n.sym.flags != {}: result = false elif optPanics in p.config.globalOptions or - (n.kind == nkSym and sfSystemModule in getModule(n.sym).flags): + (n.kind == nkSym and sfSystemModule in getModule(n.sym).flags and + sfSystemRaisesDefect notin n.sym.flags): # we know we can be strict: result = canRaise(n) else: diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index bab8ff5e3..557ea7ca6 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -147,3 +147,4 @@ proc initDefines*(symbols: StringTableRef) = defineSymbol("nimHasAmbiguousEnumHint") defineSymbol("nimHasOutParams") + defineSymbol("nimHasSystemRaisesDefect") diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index bcc786703..b60331b29 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -34,7 +34,7 @@ const wAsmNoStackFrame, wDiscardable, wNoInit, wCodegenDecl, wGensym, wInject, wRaises, wEffectsOf, wTags, wForbids, wLocks, wDelegator, wGcSafe, wConstructor, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy, - wRequires, wEnsures, wEnforceNoRaises} + wRequires, wEnsures, wEnforceNoRaises, wSystemRaisesDefect} converterPragmas* = procPragmas methodPragmas* = procPragmas+{wBase}-{wImportCpp} templatePragmas* = {wDeprecated, wError, wGensym, wInject, wDirty, @@ -1229,6 +1229,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, pragmaEnsures(c, it) of wEnforceNoRaises: sym.flags.incl sfNeverRaises + of wSystemRaisesDefect: + sym.flags.incl sfSystemRaisesDefect else: invalidPragma(c, it) elif comesFromPush and whichKeyword(ident) != wInvalid: discard "ignore the .push pragma; it doesn't apply" diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index c21eda1f9..a9ef31dc2 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -86,7 +86,7 @@ type wAsmNoStackFrame = "asmNoStackFrame", wImplicitStatic = "implicitStatic", wGlobal = "global", wCodegenDecl = "codegenDecl", wUnchecked = "unchecked", wGuard = "guard", wLocks = "locks", wPartial = "partial", wExplain = "explain", - wLiftLocals = "liftlocals", wEnforceNoRaises = "enforceNoRaises", + wLiftLocals = "liftlocals", wEnforceNoRaises = "enforceNoRaises", wSystemRaisesDefect = "systemRaisesDefect", wRedefine = "redefine", wCallsite = "callsite", wAuto = "auto", wBool = "bool", wCatch = "catch", wChar = "char", diff --git a/lib/system/indices.nim b/lib/system/indices.nim index 3f90d4399..fd6770e23 100644 --- a/lib/system/indices.nim +++ b/lib/system/indices.nim @@ -1,3 +1,6 @@ +when not defined(nimHasSystemRaisesDefect): + {.pragma: systemRaisesDefect.} + type BackwardsIndex* = distinct int ## Type that is constructed by `^` for ## reversed array accesses. @@ -16,24 +19,24 @@ template `^`*(x: int): BackwardsIndex = BackwardsIndex(x) ## echo b[^2] # => g ## ``` -proc `[]`*[T](s: openArray[T]; i: BackwardsIndex): T {.inline.} = +proc `[]`*[T](s: openArray[T]; i: BackwardsIndex): T {.inline, systemRaisesDefect.} = system.`[]`(s, s.len - int(i)) -proc `[]`*[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T {.inline.} = +proc `[]`*[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T {.inline, systemRaisesDefect.} = a[Idx(a.len - int(i) + int low(a))] -proc `[]`*(s: string; i: BackwardsIndex): char {.inline.} = s[s.len - int(i)] +proc `[]`*(s: string; i: BackwardsIndex): char {.inline, systemRaisesDefect.} = s[s.len - int(i)] -proc `[]`*[T](s: var openArray[T]; i: BackwardsIndex): var T {.inline.} = +proc `[]`*[T](s: var openArray[T]; i: BackwardsIndex): var T {.inline, systemRaisesDefect.} = system.`[]`(s, s.len - int(i)) -proc `[]`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T {.inline.} = +proc `[]`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T {.inline, systemRaisesDefect.} = a[Idx(a.len - int(i) + int low(a))] -proc `[]`*(s: var string; i: BackwardsIndex): var char {.inline.} = s[s.len - int(i)] +proc `[]`*(s: var string; i: BackwardsIndex): var char {.inline, systemRaisesDefect.} = s[s.len - int(i)] -proc `[]=`*[T](s: var openArray[T]; i: BackwardsIndex; x: T) {.inline.} = +proc `[]=`*[T](s: var openArray[T]; i: BackwardsIndex; x: T) {.inline, systemRaisesDefect.} = system.`[]=`(s, s.len - int(i), x) -proc `[]=`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) {.inline.} = +proc `[]=`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) {.inline, systemRaisesDefect.} = a[Idx(a.len - int(i) + int low(a))] = x -proc `[]=`*(s: var string; i: BackwardsIndex; x: char) {.inline.} = +proc `[]=`*(s: var string; i: BackwardsIndex; x: char) {.inline, systemRaisesDefect.} = s[s.len - int(i)] = x template `..^`*(a, b: untyped): untyped = @@ -70,7 +73,7 @@ template spliceImpl(s, a, L, b: typed): untyped = # fill the hole: for i in 0 ..< b.len: s[a+i] = b[i] -proc `[]`*[T, U: Ordinal](s: string, x: HSlice[T, U]): string {.inline.} = +proc `[]`*[T, U: Ordinal](s: string, x: HSlice[T, U]): string {.inline, systemRaisesDefect.} = ## Slice operation for strings. ## Returns the inclusive range `[s[x.a], s[x.b]]`: ## ``` @@ -82,7 +85,7 @@ proc `[]`*[T, U: Ordinal](s: string, x: HSlice[T, U]): string {.inline.} = result = newString(L) for i in 0 ..< L: result[i] = s[i + a] -proc `[]=`*[T, U: Ordinal](s: var string, x: HSlice[T, U], b: string) = +proc `[]=`*[T, U: Ordinal](s: var string, x: HSlice[T, U], b: string) {.systemRaisesDefect.} = ## Slice assignment for strings. ## ## If `b.len` is not exactly the number of elements that are referred to @@ -100,7 +103,7 @@ proc `[]=`*[T, U: Ordinal](s: var string, x: HSlice[T, U], b: string) = else: spliceImpl(s, a, L, b) -proc `[]`*[Idx, T; U, V: Ordinal](a: array[Idx, T], x: HSlice[U, V]): seq[T] = +proc `[]`*[Idx, T; U, V: Ordinal](a: array[Idx, T], x: HSlice[U, V]): seq[T] {.systemRaisesDefect.} = ## Slice operation for arrays. ## Returns the inclusive range `[a[x.a], a[x.b]]`: ## ``` @@ -112,7 +115,7 @@ proc `[]`*[Idx, T; U, V: Ordinal](a: array[Idx, T], x: HSlice[U, V]): seq[T] = result = newSeq[T](L) for i in 0..<L: result[i] = a[Idx(i + xa)] -proc `[]=`*[Idx, T; U, V: Ordinal](a: var array[Idx, T], x: HSlice[U, V], b: openArray[T]) = +proc `[]=`*[Idx, T; U, V: Ordinal](a: var array[Idx, T], x: HSlice[U, V], b: openArray[T]) {.systemRaisesDefect.} = ## Slice assignment for arrays. ## ``` ## var a = [10, 20, 30, 40, 50] @@ -126,7 +129,7 @@ proc `[]=`*[Idx, T; U, V: Ordinal](a: var array[Idx, T], x: HSlice[U, V], b: ope else: sysFatal(RangeDefect, "different lengths for slice assignment") -proc `[]`*[T; U, V: Ordinal](s: openArray[T], x: HSlice[U, V]): seq[T] = +proc `[]`*[T; U, V: Ordinal](s: openArray[T], x: HSlice[U, V]): seq[T] {.systemRaisesDefect.} = ## Slice operation for sequences. ## Returns the inclusive range `[s[x.a], s[x.b]]`: ## ``` @@ -138,7 +141,7 @@ proc `[]`*[T; U, V: Ordinal](s: openArray[T], x: HSlice[U, V]): seq[T] = newSeq(result, L) for i in 0 ..< L: result[i] = s[i + a] -proc `[]=`*[T; U, V: Ordinal](s: var seq[T], x: HSlice[U, V], b: openArray[T]) = +proc `[]=`*[T; U, V: Ordinal](s: var seq[T], x: HSlice[U, V], b: openArray[T]) {.systemRaisesDefect.} = ## Slice assignment for sequences. ## ## If `b.len` is not exactly the number of elements that are referred to diff --git a/tests/stdlib/tstring.nim b/tests/stdlib/tstring.nim index 232211471..2e8fe09e1 100644 --- a/tests/stdlib/tstring.nim +++ b/tests/stdlib/tstring.nim @@ -1,5 +1,4 @@ discard """ - matrix: "--mm:refc" targets: "c cpp js" """ |