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

drnim improvements #14471

Merged
merged 1 commit into from
May 27, 2020
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
38 changes: 27 additions & 11 deletions drnim/drnim.nim
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ const
Usage = """
drnim [options] [projectfile]

Options: Same options that the Nim compiler supports.
Options: Same options that the Nim compiler supports. Plus:

--assumeUnique Assume unique `ref` pointers. This makes the analysis unsound
but more useful for wild Nim code such as the Nim compiler
itself.
"""

proc getCommandLineDesc(conf: ConfigRef): string =
Expand Down Expand Up @@ -256,6 +260,16 @@ proc notImplemented(msg: string) {.noinline.} =
echo msg
raise newException(CannotMapToZ3Error, "; cannot map to Z3: " & msg)

proc notImplemented(n: PNode) {.noinline.} =
when defined(debug):
writeStackTrace()
raise newException(CannotMapToZ3Error, "; cannot map to Z3: " & $n)

proc notImplemented(t: PType) {.noinline.} =
when defined(debug):
writeStackTrace()
raise newException(CannotMapToZ3Error, "; cannot map to Z3: " & typeToString t)

proc translateEnsures(e, x: PNode): PNode =
if e.kind == nkSym and e.sym.kind == skResult:
result = x
Expand All @@ -277,7 +291,7 @@ proc typeToZ3(c: DrCon; t: PType): Z3_sort =
result = Z3_mk_bv_sort(ctx, 64)
#cuint(getSize(c.graph.config, t) * 8))
else:
notImplemented(typeToString(t))
notImplemented(t)

template binary(op, a, b): untyped =
var arr = [a, b]
Expand All @@ -295,7 +309,7 @@ proc nodeToDomain(c: var DrCon; n, q: PNode; opAnd: PSym): PNode =
let opLt = createMagic(c.graph, "<", mLtI)
result = buildCall(opAnd, buildCall(opLe, n[1], q), buildCall(opLt, q, n[2]))
else:
notImplemented($n)
notImplemented(n)

template quantorToZ3(fn) {.dirty.} =
template ctx: untyped = c.up.z3
Expand Down Expand Up @@ -359,8 +373,7 @@ proc nodeToZ3(c: var DrCon; n: PNode; scope: VersionScope; vars: var seq[PNode])
result = Z3_mk_fpa_numeral_double(ctx, n.floatVal, Z3_mk_fpa_sort_double(ctx))
of nkCallKinds:
assert n.len > 0
assert n[0].kind == nkSym
let operator = n[0].sym.magic
let operator = getMagic(n)
case operator
of mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc,
mEqStr, mEqSet, mEqCString:
Expand All @@ -380,7 +393,7 @@ proc nodeToZ3(c: var DrCon; n: PNode; scope: VersionScope; vars: var seq[PNode])
c.mapping[key] = result
vars.add n
else:
notImplemented(renderTree(n))
notImplemented(n)
of mHigh:
let addOpr = createMagic(c.graph, "+", mAddI)
let lenOpr = createMagic(c.graph, "len", mLengthOpenArray)
Expand Down Expand Up @@ -486,15 +499,15 @@ proc nodeToZ3(c: var DrCon; n: PNode; scope: VersionScope; vars: var seq[PNode])
vars.add n

if pointer(result) == nil:
notImplemented(renderTree(n))
notImplemented(n)
of nkStmtListExpr, nkPar:
var isTrivial = true
for i in 0..n.len-2:
isTrivial = isTrivial and n[i].kind in {nkEmpty, nkCommentStmt}
if isTrivial:
result = rec n[^1]
else:
notImplemented(renderTree(n))
notImplemented(n)
of nkHiddenDeref:
result = rec n[0]
else:
Expand All @@ -507,7 +520,7 @@ proc nodeToZ3(c: var DrCon; n: PNode; scope: VersionScope; vars: var seq[PNode])
c.mapping[key] = result
vars.add n
else:
notImplemented(renderTree(n))
notImplemented(n)

proc addRangeInfo(c: var DrCon, n: PNode; scope: VersionScope, res: var seq[Z3_ast]) =
var cmpOp = mLeI
Expand Down Expand Up @@ -748,7 +761,7 @@ template config(c: typed): untyped = c.graph.config

proc addFact(c: DrnimContext; n: PNode) =
let v = c.currentScope
if n[0].kind == nkSym and n[0].sym.magic in {mOr, mAnd}:
if n.kind in nkCallKinds and n[0].kind == nkSym and n[0].sym.magic in {mOr, mAnd}:
c.addFact(n[1])
c.facts.add((n, v))

Expand Down Expand Up @@ -1051,7 +1064,9 @@ proc traverse(c: DrnimContext; n: PNode) =
let arg = n[1]
freshVersion(c, arg)
traverse(c, arg)
addAsgnFact(c, arg, newNodeIT(nkObjConstr, arg.info, arg.typ))
let x = newNodeIT(nkObjConstr, arg.info, arg.typ)
x.add arg
addAsgnFact(c, arg, x)
of mArrGet, mArrPut:
#if optStaticBoundsCheck in c.currOptions: checkBounds(c, n[1], n[2])
discard
Expand Down Expand Up @@ -1244,6 +1259,7 @@ proc processCmdLine(pass: TCmdLinePass, cmd: string; config: ConfigRef) =
rawMessage(config, errGenerated, errArgsNeedRunOption)

proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
incl conf.options, optStaticBoundsCheck
let self = NimProg(
supportsStdinFile: true,
processCmdLine: processCmdLine,
Expand Down
3 changes: 3 additions & 0 deletions drnim/tests/config.nims
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ switch("path", "$nim/testament/lib") # so we can `import stdtest/foo` in this di
switch("colors", "off")
switch("listFullPaths", "off")
switch("excessiveStackTrace", "off")

# we only want to check the marked parts in the tests:
switch("staticBoundChecks", "off")