fixes #20026; marks system procs which can raise defects (#20864)

* marks system procs which can raise defects

* add tests

* add more systemRaisesDefect

* add comment
This commit is contained in:
ringabout 2022-11-23 03:07:00 +08:00 • committed by GitHub
commit 0448f30fd9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 26 additions and 19 deletions

View file

@ -299,6 +299,7 @@ type
sfInjectDestructors # whether the proc needs the 'injectdestructors' transformation sfInjectDestructors # whether the proc needs the 'injectdestructors' transformation
sfNeverRaises # proc can never raise an exception, not even OverflowDefect sfNeverRaises # proc can never raise an exception, not even OverflowDefect
# or out-of-memory # or out-of-memory
sfSystemRaisesDefect # proc in the system can raise defects
sfUsedInFinallyOrExcept # symbol is used inside an 'except' or 'finally' sfUsedInFinallyOrExcept # symbol is used inside an 'except' or 'finally'
sfSingleUsedTemp # For temporaries that we know will only be used once sfSingleUsedTemp # For temporaries that we know will only be used once
sfNoalias # 'noalias' annotation, means C's 'restrict' sfNoalias # 'noalias' annotation, means C's 'restrict'

View file

@ -14,7 +14,8 @@ proc canRaiseDisp(p: BProc; n: PNode): bool =
if n.kind == nkSym and {sfNeverRaises, sfImportc, sfCompilerProc} * n.sym.flags != {}: if n.kind == nkSym and {sfNeverRaises, sfImportc, sfCompilerProc} * n.sym.flags != {}:
result = false result = false
elif optPanics in p.config.globalOptions or 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: # we know we can be strict:
result = canRaise(n) result = canRaise(n)
else: else:

View file

@ -147,3 +147,4 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimHasAmbiguousEnumHint") defineSymbol("nimHasAmbiguousEnumHint")
defineSymbol("nimHasOutParams") defineSymbol("nimHasOutParams")
defineSymbol("nimHasSystemRaisesDefect")

View file

@ -34,7 +34,7 @@ const
wAsmNoStackFrame, wDiscardable, wNoInit, wCodegenDecl, wAsmNoStackFrame, wDiscardable, wNoInit, wCodegenDecl,
wGensym, wInject, wRaises, wEffectsOf, wTags, wForbids, wLocks, wDelegator, wGcSafe, wGensym, wInject, wRaises, wEffectsOf, wTags, wForbids, wLocks, wDelegator, wGcSafe,
wConstructor, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy, wConstructor, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy,
wRequires, wEnsures, wEnforceNoRaises} wRequires, wEnsures, wEnforceNoRaises, wSystemRaisesDefect}
converterPragmas* = procPragmas converterPragmas* = procPragmas
methodPragmas* = procPragmas+{wBase}-{wImportCpp} methodPragmas* = procPragmas+{wBase}-{wImportCpp}
templatePragmas* = {wDeprecated, wError, wGensym, wInject, wDirty, templatePragmas* = {wDeprecated, wError, wGensym, wInject, wDirty,
@ -1229,6 +1229,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
pragmaEnsures(c, it) pragmaEnsures(c, it)
of wEnforceNoRaises: of wEnforceNoRaises:
sym.flags.incl sfNeverRaises sym.flags.incl sfNeverRaises
of wSystemRaisesDefect:
sym.flags.incl sfSystemRaisesDefect
else: invalidPragma(c, it) else: invalidPragma(c, it)
elif comesFromPush and whichKeyword(ident) != wInvalid: elif comesFromPush and whichKeyword(ident) != wInvalid:
discard "ignore the .push pragma; it doesn't apply" discard "ignore the .push pragma; it doesn't apply"

View file

@ -86,7 +86,7 @@ type
wAsmNoStackFrame = "asmNoStackFrame", wImplicitStatic = "implicitStatic", wAsmNoStackFrame = "asmNoStackFrame", wImplicitStatic = "implicitStatic",
wGlobal = "global", wCodegenDecl = "codegenDecl", wUnchecked = "unchecked", wGlobal = "global", wCodegenDecl = "codegenDecl", wUnchecked = "unchecked",
wGuard = "guard", wLocks = "locks", wPartial = "partial", wExplain = "explain", wGuard = "guard", wLocks = "locks", wPartial = "partial", wExplain = "explain",
wLiftLocals = "liftlocals", wEnforceNoRaises = "enforceNoRaises", wLiftLocals = "liftlocals", wEnforceNoRaises = "enforceNoRaises", wSystemRaisesDefect = "systemRaisesDefect",
wRedefine = "redefine", wCallsite = "callsite", wRedefine = "redefine", wCallsite = "callsite",
wAuto = "auto", wBool = "bool", wCatch = "catch", wChar = "char", wAuto = "auto", wBool = "bool", wCatch = "catch", wChar = "char",

View file

@ -1,3 +1,6 @@
when not defined(nimHasSystemRaisesDefect):
{.pragma: systemRaisesDefect.}
type type
BackwardsIndex* = distinct int ## Type that is constructed by `^` for BackwardsIndex* = distinct int ## Type that is constructed by `^` for
## reversed array accesses. ## reversed array accesses.
@ -16,24 +19,24 @@ template `^`*(x: int): BackwardsIndex = BackwardsIndex(x)
## echo b[^2] # => g ## 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)) 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))] 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)) 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))] 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) 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 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 s[s.len - int(i)] = x
template `..^`*(a, b: untyped): untyped = template `..^`*(a, b: untyped): untyped =
@ -70,7 +73,7 @@ template spliceImpl(s, a, L, b: typed): untyped =
# fill the hole: # fill the hole:
for i in 0 ..< b.len: s[a+i] = b[i] 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. ## Slice operation for strings.
## Returns the inclusive range `[s[x.a], s[x.b]]`: ## 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) result = newString(L)
for i in 0 ..< L: result[i] = s[i + a] 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. ## Slice assignment for strings.
## ##
## If `b.len` is not exactly the number of elements that are referred to ## 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: else:
spliceImpl(s, a, L, b) 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. ## Slice operation for arrays.
## Returns the inclusive range `[a[x.a], a[x.b]]`: ## 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) result = newSeq[T](L)
for i in 0..<L: result[i] = a[Idx(i + xa)] 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. ## Slice assignment for arrays.
## ``` ## ```
## var a = [10, 20, 30, 40, 50] ## 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: else:
sysFatal(RangeDefect, "different lengths for slice assignment") 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. ## Slice operation for sequences.
## Returns the inclusive range `[s[x.a], s[x.b]]`: ## 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) newSeq(result, L)
for i in 0 ..< L: result[i] = s[i + a] 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. ## Slice assignment for sequences.
## ##
## If `b.len` is not exactly the number of elements that are referred to ## If `b.len` is not exactly the number of elements that are referred to

View file

@ -1,5 +1,4 @@
discard """ discard """
matrix: "--mm:refc"
targets: "c cpp js" targets: "c cpp js"
""" """