Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass noReturn pragma to C code. #2657

Merged
merged 4 commits into from
May 8, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions compiler/cgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -676,8 +676,11 @@ proc genProcAux(m: BModule, prc: PSym) =
closureSetup(p, prc)
genStmts(p, prc.getBody) # modifies p.locals, p.init, etc.
var generatedProc: Rope
if sfNoReturn in prc.flags:
if hasDeclspec in extccomp.CC[extccomp.cCompiler].props:
header = "__declspec(noreturn) " & header
if sfPure in prc.flags:
if hasNakedDeclspec in extccomp.CC[extccomp.cCompiler].props:
if hasDeclspec in extccomp.CC[extccomp.cCompiler].props:
header = "__declspec(naked) " & header
generatedProc = rfmt(nil, "$N$1 {$n$2$3$4}$N$N",
header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts))
Expand Down Expand Up @@ -720,8 +723,10 @@ proc genProcPrototype(m: BModule, sym: PSym) =
var header = genProcHeader(m, sym)
if sym.typ.callConv != ccInline and crossesCppBoundary(m, sym):
header = "extern \"C\" " & header
if sfPure in sym.flags and hasNakedAttribute in CC[cCompiler].props:
if sfPure in sym.flags and hasAttribute in CC[cCompiler].props:
header.add(" __attribute__((naked))")
if sfNoReturn in sym.flags and hasAttribute in CC[cCompiler].props:
header.add(" __attribute__((noreturn))")
add(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header))

proc genProcNoForward(m: BModule, prc: PSym) =
Expand Down
8 changes: 4 additions & 4 deletions compiler/extccomp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ type
hasAssume, # CC has __assume (Visual C extension)
hasGcGuard, # CC supports GC_GUARD to keep stack roots
hasGnuAsm, # CC's asm uses the absurd GNU assembler syntax
hasNakedDeclspec, # CC has __declspec(naked)
hasNakedAttribute # CC has __attribute__((naked))
hasDeclspec, # CC has __declspec(X)
hasAttribute, # CC has __attribute__((X))
TInfoCCProps* = set[TInfoCCProp]
TInfoCC* = tuple[
name: string, # the short name of the compiler
Expand Down Expand Up @@ -85,7 +85,7 @@ compiler gcc:
structStmtFmt: "$1 $3 $2 ", # struct|union [packed] $name
packedPragma: "__attribute__((__packed__))",
props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm,
hasNakedAttribute})
hasAttribute})

# LLVM Frontend for GCC/G++
compiler llvmGcc:
Expand Down Expand Up @@ -127,7 +127,7 @@ compiler vcc:
asmStmtFrmt: "__asm{$n$1$n}$n",
structStmtFmt: "$3$n$1 $2",
packedPragma: "#pragma pack(1)",
props: {hasCpp, hasAssume, hasNakedDeclspec})
props: {hasCpp, hasAssume, hasDeclspec})

# Intel C/C++ Compiler
compiler icl:
Expand Down
19 changes: 10 additions & 9 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1110,7 +1110,7 @@ var programResult* {.exportc: "nim_program_result".}: int
## prematurely using ``quit``, this value is ignored.

proc quit*(errorcode: int = QuitSuccess) {.
magic: "Exit", importc: "exit", header: "<stdlib.h>", noReturn.}
magic: "Exit", importc: "exit", header: "<stdlib.h>", noreturn.}
## Stops the program immediately with an exit code.
##
## Before stopping the program the "quit procedures" are called in the
Expand Down Expand Up @@ -2270,20 +2270,21 @@ when hostOS == "standalone":
include panicoverride

when not declared(sysFatal):
template sysFatal(exceptn: typedesc, message: string) =
when hostOS == "standalone":
when hostOS == "standalone":
proc sysFatal(exceptn: typedesc, message: string) {.inline.} =
panic(message)
else:

proc sysFatal(exceptn: typedesc, message, arg: string) {.inline.} =
rawoutput(message)
panic(arg)
else:
proc sysFatal(exceptn: typedesc, message: string) {.inline, noReturn.} =
var e: ref exceptn
new(e)
e.msg = message
raise e

template sysFatal(exceptn: typedesc, message, arg: string) =
when hostOS == "standalone":
rawoutput(message)
panic(arg)
else:
proc sysFatal(exceptn: typedesc, message, arg: string) {.inline, noReturn.} =
var e: ref exceptn
new(e)
e.msg = message & arg
Expand Down
8 changes: 4 additions & 4 deletions lib/system/arithm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@

# simple integer arithmetic with overflow checking

proc raiseOverflow {.compilerproc, noinline, noreturn.} =
proc raiseOverflow {.compilerproc, noinline.} =
# a single proc to reduce code size to a minimum
sysFatal(OverflowError, "over- or underflow")

proc raiseDivByZero {.compilerproc, noinline, noreturn.} =
proc raiseDivByZero {.compilerproc, noinline.} =
sysFatal(DivByZeroError, "division by zero")

proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
Expand Down Expand Up @@ -327,13 +327,13 @@ when not declared(mulInt):
# We avoid setting the FPU control word here for compatibility with libraries
# written in other languages.

proc raiseFloatInvalidOp {.noinline, noreturn.} =
proc raiseFloatInvalidOp {.noinline.} =
sysFatal(FloatInvalidOpError, "FPU operation caused a NaN result")

proc nanCheck(x: float64) {.compilerProc, inline.} =
if x != x: raiseFloatInvalidOp()

proc raiseFloatOverflow(x: float64) {.noinline, noreturn.} =
proc raiseFloatOverflow(x: float64) {.noinline.} =
if x > 0.0:
sysFatal(FloatOverflowError, "FPU operation caused an overflow")
else:
Expand Down
6 changes: 3 additions & 3 deletions lib/system/chcks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@

# Implementation of some runtime checks.

proc raiseRangeError(val: BiggestInt) {.compilerproc, noreturn, noinline.} =
proc raiseRangeError(val: BiggestInt) {.compilerproc, noinline.} =
when hostOS == "standalone":
sysFatal(RangeError, "value out of range")
else:
sysFatal(RangeError, "value out of range: ", $val)

proc raiseIndexError() {.compilerproc, noreturn, noinline.} =
proc raiseIndexError() {.compilerproc, noinline.} =
sysFatal(IndexError, "index out of bounds")

proc raiseFieldError(f: string) {.compilerproc, noreturn, noinline.} =
proc raiseFieldError(f: string) {.compilerproc, noinline.} =
sysFatal(FieldError, f, " is not accessible")

proc chckIndx(i, a, b: int): int =
Expand Down
6 changes: 3 additions & 3 deletions tests/manyloc/standalone/panicoverride.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ proc exit(code: int) {.importc, header: "<stdlib.h>", cdecl.}
proc rawoutput(s: string) =
printf("%s\n", s)

proc panic(s: string) =
proc panic(s: string) {.noreturn.} =
rawoutput(s)
exit(1)

# Alternatively we also could implement these 2 here:
#
# template sysFatal(exceptn: typeDesc, message: string)
# template sysFatal(exceptn: typeDesc, message, arg: string)
# proc sysFatal(exceptn: typeDesc, message: string) {.noReturn.}
# proc sysFatal(exceptn: typeDesc, message, arg: string) {.noReturn.}

{.pop.}