[topl] Remove nondet marker

Summary:
The explicit marker for nondeterministic states was used to speed up the
shallow implementations of Topl, which ar enow removed.

Reviewed By: jvillard

Differential Revision: D27297019

fbshipit-source-id: 0fce93817
master
Radu Grigore 4 years ago committed by Facebook GitHub Bot
parent 55af83de03
commit 6f83c45e47

@ -47,8 +47,4 @@ type transition = {source: vertex; target: vertex; label: label option}
(* TODO(rgrigore): Check that registers are read only after being initialized *) (* TODO(rgrigore): Check that registers are read only after being initialized *)
type t = type t =
{ name: property_name {name: property_name; message: string option; prefixes: string list; transitions: transition list}
; message: string option
; prefixes: string list
; nondet: string list
; transitions: transition list }

@ -31,16 +31,14 @@ type tindex = int
type transition = {source: vindex; target: vindex; label: ToplAst.label option} type transition = {source: vindex; target: vindex; label: ToplAst.label option}
(** - INV1: Array.length states = Array.length outgoing = Array.length nondets (** - INV1: Array.length transitions = Array.length skips
- INV2: Array.length transitions = Array.length skips - INV2: each index of [transitions] occurs exactly once in one of [outgoing]'s lists
- INV3: each index of [transitions] occurs exactly once in one of [outgoing]'s lists - INV3: max_args is the maximum length of the arguments list in a label on a transition
- INV4: max_args is the maximum length of the arguments list in a label on a transition
The fields marked as redundant are computed from the others (when the automaton is built), and The fields marked as redundant are computed from the others (when the automaton is built), and
are cached for speed. *) are cached for speed. *)
type t = type t =
{ states: vname array { states: vname array
; nondets: bool array (* redundant *)
; transitions: transition array ; transitions: transition array
; skips: bool array (* redundant *) ; skips: bool array (* redundant *)
; outgoing: tindex list array ; outgoing: tindex list array
@ -76,7 +74,7 @@ let make properties =
Array.of_list (List.dedup_and_sort ~compare:Vname.compare (List.concat_map ~f properties)) Array.of_list (List.dedup_and_sort ~compare:Vname.compare (List.concat_map ~f properties))
in in
Array.iteri ~f:(fun i (p, v) -> tt "state[%d]=(%s,%s)@\n" i p v) states ; Array.iteri ~f:(fun i (p, v) -> tt "state[%d]=(%s,%s)@\n" i p v) states ;
let vindex_opt, vindex = index_in (module Vname.Table) states in let _vindex_opt, vindex = index_in (module Vname.Table) states in
let vindex = vindex "vertex" in let vindex = vindex "vertex" in
let transitions : transition array = let transitions : transition array =
let f p = let f p =
@ -118,30 +116,12 @@ let make properties =
|> Array.max_elt ~compare:Int.compare |> Array.max_elt ~compare:Int.compare
|> Option.value ~default:0 |> succ |> Option.value ~default:0 |> succ
in in
let nondets : bool array =
let vcount = Array.length states in
let a = Array.create ~len:vcount false in
let f ToplAst.{nondet; name; _} =
let set_nondet state =
match vindex_opt (name, state) with
| Some i ->
a.(i) <- true
| None ->
L.user_warning
"TOPL: %s declared as nondet, but it appears in no transition of property %s" state
name
in
List.iter ~f:set_nondet nondet
in
List.iter ~f properties ;
a
in
let skips : bool array = let skips : bool array =
(* TODO(rgrigore): Rename "anys"? *) (* TODO(rgrigore): Rename "anys"? *)
let is_skip {label} = Option.is_none label in let is_skip {label} = Option.is_none label in
Array.map ~f:is_skip transitions Array.map ~f:is_skip transitions
in in
{states; nondets; transitions; skips; outgoing; vindex; max_args} {states; transitions; skips; outgoing; vindex; max_args}
let vname a i = a.states.(i) let vname a i = a.states.(i)

@ -56,7 +56,6 @@ rule raw_token = parse
| "prefix" { PREFIX } | "prefix" { PREFIX }
| "property" { PROPERTY } | "property" { PROPERTY }
| "message" { MESSAGE } | "message" { MESSAGE }
| "nondet" { NONDET }
| "when" { WHEN } | "when" { WHEN }
| ['a'-'z'] id_tail as id { LID id } | ['a'-'z'] id_tail as id { LID id }
| ['A'-'Z'] id_tail as id { UID id } | ['A'-'Z'] id_tail as id { UID id }

@ -30,7 +30,6 @@
%token LT %token LT
%token MESSAGE %token MESSAGE
%token NE %token NE
%token NONDET
%token PREFIX %token PREFIX
%token PROPERTY %token PROPERTY
%token RC %token RC
@ -46,16 +45,14 @@
properties: ps=one_property* EOF { ps } properties: ps=one_property* EOF { ps }
one_property: one_property:
PROPERTY name=identifier LC message=message? prefixes=prefix* nondet=nondet PROPERTY name=identifier LC message=message? prefixes=prefix*
transitions=transition* RC transitions=transition* RC
{ ToplAst.{name; message; prefixes; nondet; transitions} } { ToplAst.{name; message; prefixes; transitions} }
message: MESSAGE s=STRING { s } message: MESSAGE s=STRING { s }
prefix: PREFIX s=STRING { s } prefix: PREFIX s=STRING { s }
nondet: NONDET LP ns=state* RP { ns }
transition: transition:
source=state ARROW target=state COLON label=label source=state ARROW target=state COLON label=label
{ ToplAst.{source; target; label} } { ToplAst.{source; target; label} }

@ -1,5 +1,4 @@
property BaosRetrieveWithoutFlush property BaosRetrieveWithoutFlush
nondet (start)
start -> start: * start -> start: *
start -> valid: ".*OutputStream"(X, Y, Ret) => x := X; y := Y start -> valid: ".*OutputStream"(X, Y, Ret) => x := X; y := Y
valid -> invalid: ".*OutputStream.write.*"(X, Ia, Ret) when X == x valid -> invalid: ".*OutputStream.write.*"(X, Ia, Ret) when X == x

@ -1,4 +1,3 @@
property MaxArgs property MaxArgs
nondet (start)
start -> start: * start -> start: *
start -> error: "CompareArgs.max"(Ignore, I, J, IgnoreRet) when I >= J start -> error: "CompareArgs.max"(Ignore, I, J, IgnoreRet) when I >= J

@ -2,7 +2,6 @@ property HasNext
prefix "Iterator" prefix "Iterator"
prefix "List" prefix "List"
prefix "Scanner" prefix "Scanner"
nondet (start)
start -> start: * start -> start: *
start -> invalid: iterator(Ignore, RetIter) => i := RetIter start -> invalid: iterator(Ignore, RetIter) => i := RetIter
start -> invalid: Scanner(Iter, IgnoreA, IgnoreB) => i := Iter // For constructors, "this" is first argument, and there's a dummy return start -> invalid: Scanner(Iter, IgnoreA, IgnoreB) => i := Iter // For constructors, "this" is first argument, and there's a dummy return

@ -1,6 +1,5 @@
property ImmutableArrayModified property ImmutableArrayModified
prefix "ImmutableArray" prefix "ImmutableArray"
nondet (start)
start -> start: * start -> start: *
start -> tracking: getTestArray(IgnoreObject, Array) => a := Array start -> tracking: getTestArray(IgnoreObject, Array) => a := Array
tracking -> error: #ArrayWrite(Array, IgnoreIndex) when a == Array tracking -> error: #ArrayWrite(Array, IgnoreIndex) when a == Array

@ -8,7 +8,6 @@
property InterleavedResponse property InterleavedResponse
message "A ServletResponse was asked for both a writer and a stream." message "A ServletResponse was asked for both a writer and a stream."
prefix "ServletResponse" prefix "ServletResponse"
nondet (start)
start -> start: * start -> start: *
start -> gotWriter: getWriter(R, IgnoreRet) => r := R start -> gotWriter: getWriter(R, IgnoreRet) => r := R
start -> gotStream: getOutputStream(R, IgnoreRet) => r := R start -> gotStream: getOutputStream(R, IgnoreRet) => r := R
@ -17,7 +16,6 @@ property InterleavedResponse
property ForwardUncommitted property ForwardUncommitted
message "A ServletResponse was forwarded before being committed." message "A ServletResponse was forwarded before being committed."
nondet (start)
start -> start: * start -> start: *
start -> gotChannel: "ServletResponse.\\(getWriter\\|getOutputStream\\)"(R, C) => r := R; c := C start -> gotChannel: "ServletResponse.\\(getWriter\\|getOutputStream\\)"(R, C) => r := R; c := C
gotChannel -> ok: "\\(PrintWriter\\|ServletOutputStream\\).flush.*"(C, IgnoreRet) when C == c gotChannel -> ok: "\\(PrintWriter\\|ServletOutputStream\\).flush.*"(C, IgnoreRet) when C == c

@ -1,6 +1,5 @@
property SkipAfterRemove property SkipAfterRemove
prefix "ArrayList" prefix "ArrayList"
nondet (start)
start -> start: * start -> start: *
start -> removed: remove(Collection, Index, IgnoreRet) => c := Collection; i := Index start -> removed: remove(Collection, Index, IgnoreRet) => c := Collection; i := Index
removed -> ok: get(Collection, Index, IgnoreRet) when i == Index && c == Collection removed -> ok: get(Collection, Index, IgnoreRet) when i == Index && c == Collection

@ -1,5 +1,4 @@
property ShouldUseEntries property ShouldUseEntries
nondet (start iteratingKeys)
start -> start: * start -> start: *
start -> gotKeys: "Map.keySet"(M, S) => m := M; s := S start -> gotKeys: "Map.keySet"(M, S) => m := M; s := S
gotKeys -> iteratingKeys: "Set.iterator"(S, I) when S == s => i := I gotKeys -> iteratingKeys: "Set.iterator"(S, I) when S == s => i := I

@ -1,7 +1,6 @@
property TaintTrack property TaintTrack
prefix "StringBuilder" prefix "StringBuilder"
prefix "Taint" prefix "Taint"
nondet (start building track)
// We start tracking when we see calls to Taint.badString // We start tracking when we see calls to Taint.badString
start -> start: * start -> start: *

Loading…
Cancel
Save