Skip to content

Commit

Permalink
Merge pull request #1092 from goblint/fix-gobview-search
Browse files Browse the repository at this point in the history
Towards fixing GobView search: Avoid truncation of very large integers
  • Loading branch information
stilscher authored Feb 7, 2024
2 parents cab0404 + d53037a commit 5e3ed6c
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 14 deletions.
2 changes: 1 addition & 1 deletion gobview
Submodule gobview updated 57 files
+3 −0 dune-project
+3 −1 gobview.opam
+11 −16 gobview.opam.locked
+0 −1 gobview.opam.template
+6 −0 runtime/stubs.js
+3 −3 src/App.re
+0 −46 src/Graphviz.mli
+4 −3 src/Main.re
+0 −5 src/bindings/dune
+0 −33 src/bindings/errorBoundary.mli
+3 −3 src/bindings/monaco.mli
+0 −6 src/dune
+0 −0 src/gvConstants.ml
+0 −2 src/react-requires.js
+14 −12 src/state/search.ml
+2 −3 src/ui/base/button.re
+14 −16 src/ui/base/collapsibleList.re
+5 −7 src/ui/base/collapsibleListItem.re
+6 −15 src/ui/base/gvEditor.re
+3 −3 src/ui/base/input.re
+2 −0 src/ui/base/invalidFeedback.re
+2 −1 src/ui/base/label.re
+6 −8 src/ui/base/link.re
+9 −7 src/ui/base/listInput.re
+5 −5 src/ui/base/select.re
+3 −2 src/ui/base/textArea.re
+2 −3 src/ui/base/validatedInput.re
+1 −1 src/ui/content/Content.re
+4 −3 src/ui/content/gvBreadcrumb.re
+3 −3 src/ui/content/gvFileView.re
+6 −4 src/ui/content/gvFuncView.re
+3 −3 src/ui/panel/DeadCodeView.re
+5 −5 src/ui/panel/Panel.re
+2 −0 src/ui/panel/ParameterView.re
+22 −22 src/ui/panel/WarningView.re
+3 −3 src/ui/panel/gvStatisticsView.re
+2 −1 src/ui/search/searchExpressionBuilder.re
+2 −1 src/ui/search/searchFindBuilder.re
+2 −1 src/ui/search/searchKindBuilder.re
+2 −1 src/ui/search/searchModeBuilder.re
+4 −4 src/ui/search/searchQueryBuilder.re
+4 −2 src/ui/search/searchQueryEditor.re
+5 −4 src/ui/search/searchQueryView.re
+16 −10 src/ui/search/searchResultView.re
+2 −1 src/ui/search/searchStructureBuilder.re
+3 −2 src/ui/search/searchTargetBuilder.re
+1 −0 src/ui/search/searchView.re
+15 −15 src/ui/sidebar/SidebarLeft.re
+6 −6 src/ui/sidebar/SidebarRight.re
+14 −15 src/ui/sidebar/gvFileList.re
+4 −4 src/ui/state/gvAnalysesView.re
+2 −3 src/ui/state/gvGlobalStateView.re
+4 −6 src/ui/state/gvNodeStateView.re
+10 −11 src/ui/state/gvRepresentationView.re
+6 −0 src/utils/ErrorBoundary.ml
+10 −0 src/utils/Graphviz.ml
+0 −56 src/utils/utils.ml
66 changes: 66 additions & 0 deletions scripts/test-gobview.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,72 @@ def serve():
panel = browser.find_element(By.CLASS_NAME, "panel")
print("found DOM elements main, sidebar-left, sidebar-right, content and panel")

# test syntactic search
leftS.find_element(By.LINK_TEXT, "Search").click()
leftS.find_element(By.CLASS_NAME, "switch-to-json").click()
textfield = leftS.find_element(By.CLASS_NAME, "form-control")
textfield.clear()
textfield.send_keys('{"kind":["var"],"target":["name","fail"],"find":["uses"],"mode":["Must"]}')
leftS.find_element(By.CLASS_NAME, "exec-button").click()
results = leftS.find_elements(By.CLASS_NAME, "list-group-item")
locations = []
for r in results:
for tr in r.find_elements(By.TAG_NAME, "tr"):
if tr.find_element(By.TAG_NAME, "th").text == "Location":
locations.insert(0,tr.find_element(By.TAG_NAME, "td").find_element(By.TAG_NAME, "a").text)

print("syntactic search for variable use of 'fail' found", len(results), "results")
for l in locations:
print(l)
assert(len(results) == 2)
assert("tests/regression/00-sanity/01-assert.c:7" in locations)
assert("tests/regression/00-sanity/01-assert.c:12" in locations)

# clear results
leftS.find_element(By.CLASS_NAME, "clear-btn").click()

# test semantic search 1
textfield = leftS.find_element(By.CLASS_NAME, "form-control")
textfield.clear()
textfield.send_keys('{"kind":["var"],"target":["name","success"],"find":["uses"],"expression":"success == 1","mode":["Must"]}')
leftS.find_element(By.CLASS_NAME, "exec-button").click()
results = leftS.find_elements(By.CLASS_NAME, "list-group-item")
locations = []
for r in results:
for tr in r.find_elements(By.TAG_NAME, "tr"):
if tr.find_element(By.TAG_NAME, "th").text == "Location":
locations.insert(0,tr.find_element(By.TAG_NAME, "td").find_element(By.TAG_NAME, "a").text)

print("semantic search for variable use of 'success' where it must be 1 found", len(results), "results")
for l in locations:
print(l)
assert(len(results) == 2)
assert("tests/regression/00-sanity/01-assert.c:10" in locations)
assert("tests/regression/00-sanity/01-assert.c:5" in locations)

# clear results
leftS.find_element(By.CLASS_NAME, "clear-btn").click()

# test semantic search 2
textfield = leftS.find_element(By.CLASS_NAME, "form-control")
textfield.clear()
textfield.send_keys('{"kind":["var"],"target":["name","success"],"find":["uses"],"expression":"success == 0","mode":["Must"]}')
leftS.find_element(By.CLASS_NAME, "exec-button").click()
results = leftS.find_elements(By.CLASS_NAME, "list-group-item")
locations = []
for r in results:
for tr in r.find_elements(By.TAG_NAME, "tr"):
if tr.find_element(By.TAG_NAME, "th").text == "Location":
locations.insert(0,tr.find_element(By.TAG_NAME, "td").find_element(By.TAG_NAME, "a").text)

print("semantic search for variable use of 'success' where it must be 0 found", len(results), "results")
for l in locations:
print(l)
assert(len(results) == 0)

# close "No results found" alert
leftS.find_element(By.CLASS_NAME, "btn-close").click()

cleanup(browser, thread)

except Exception as e:
Expand Down
1 change: 0 additions & 1 deletion src/common/framework/cfgTools.ml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ let rec pretty_edges () = function
| [_,x] -> Edge.pretty_plain () x
| (_,x)::xs -> Pretty.dprintf "%a; %a" Edge.pretty_plain x pretty_edges xs


let node_scc_global = NH.create 113

exception Not_connect of fundec
Expand Down
10 changes: 3 additions & 7 deletions src/common/util/cilfacade.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ include Cilfacade0

(** Command for assigning an id to a varinfo. All varinfos directly created by Goblint should be modified by this method *)
let create_var (var: varinfo) =
(* TODO Hack: this offset should preempt conflicts with ids generated by CIL *)
let start_id = 10_000_000_000 in
(* Hack: using negative integers should preempt conflicts with ids generated by CIL *)
let hash = Hashtbl.hash { var with vid = 0 } in
let hash = if hash < start_id then hash + start_id else hash in
{ var with vid = hash }
{ var with vid = - hash } (* Hashtbl.hash returns non-negative integer *)


(** Is character type (N1570 6.2.5.15)? *)
Expand Down Expand Up @@ -531,9 +529,7 @@ let stmt_fundecs: fundec StmtH.t ResettableLazy.t =


let get_pseudo_return_id fd =
let start_id = 10_000_000_000 in (* TODO get max_sid? *)
let sid = Hashtbl.hash fd.svar.vid in (* Need pure sid instead of Cil.new_sid for incremental, similar to vid in Cilfacade.create_var. We only add one return stmt per loop, so the hash from the functions vid should be unique. *)
if sid < start_id then sid + start_id else sid
- fd.svar.vid (* Need pure sid instead of Cil.new_sid for incremental, similar to vid in Cilfacade.create_var. We only add one return stmt per loop, so the hash from the functions vid should be unique. *)

let pseudo_return_to_fun = StmtH.create 113

Expand Down
14 changes: 9 additions & 5 deletions src/transform/expressionEvaluation.ml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type query =
structure : (CodeQuery.structure [@default None_s]);
limitation : (CodeQuery.constr [@default None_c]);

expression : string;
expression : (string option [@default None]);
mode : [ `Must | `May ];

} [@@deriving yojson]
Expand Down Expand Up @@ -60,7 +60,11 @@ struct

val global_variables =
file.globals
|> List.filter_map (function Cil.GVar (v, _, _) -> Some (v.vname, Cil.Fv v) | _ -> None)
|> List.filter_map (function
| Cil.GVar (v, _, _) -> Some (v.vname, Cil.Fv v)
| Cil.GFun (f, l) -> Some (f.svar.vname, Cil.Fv f.svar)
| Cil.GVarDecl (v, l) -> Some (v.vname, Cil.Fv v)
| _ -> None)
val statements =
file.globals
|> List.filter_map (function Cil.GFun (f, _) -> Some f | _ -> None)
Expand All @@ -77,7 +81,7 @@ struct
(* Compute the available local variables *)
let local_variables =
match Hashtbl.find_option statements location with
| Some (function_definition, _) -> function_definition.slocals |> List.map (fun (v : Cil.varinfo) -> v.vname, Cil.Fv v)
| Some (fd, _) -> fd.slocals @ fd.sformals |> List.map (fun (v : Cil.varinfo) -> v.vname, Cil.Fv v)
| None -> []
in
(* Parse expression *)
Expand Down Expand Up @@ -191,8 +195,8 @@ struct
|> List.group file_compare
(* Sort, remove duplicates, ungroup *)
|> List.concat_map (fun ls -> List.sort_uniq byte_compare ls)
(* Semantic queries *)
|> List.map (fun (n, l, s, i) -> ((n, l, s, i), evaluator#evaluate l query.expression))
(* Semantic queries if query.expression is some *)
|> List.map (fun (n, l, s, i) -> ((n, l, s, i), Option.map_default (evaluator#evaluate l) (Some true) query.expression))
in
let print ((_, loc, _, _), res) =
match res with
Expand Down

0 comments on commit 5e3ed6c

Please sign in to comment.