-
Notifications
You must be signed in to change notification settings - Fork 77
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
Run dead code analysis with reanalyze #737
Conversation
Looks like I'll have to open a PR for Gobview as well. Will do that in a moment. |
@@ -119,6 +119,7 @@ struct | |||
| _ -> false | |||
|
|||
(* kill predicate for must-equality kind of analyses*) | |||
(* TODO: why unused? how different from below? *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They seem to be virtually identical, except the one below being a fair bit more chaotic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it might have been copied there, but without completely rewriting this all, I'd rather not touch this analysis more than necessary.
@@ -151,6 +152,7 @@ struct | |||
let bt = unrollTypeDeep (Cilfacade.typeOf b) in | |||
type_may_change_t a bt | |||
|
|||
(* TODO: why unused? how different from below? *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are very similar, but the code below handles more cases, but is also considerably more weird.
@@ -117,6 +115,7 @@ struct | |||
| false, false -> join x y | |||
*) | |||
|
|||
(* TODO: overrides is_top, but not top? *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is some kind of hack to avoid the creation of top addresses as this will fail from HoarePO
. What is a bit strange is that is_top
answers true as soon as the Addr.UnknownPtr
is in the set, but top_ptr
is defined as
let top_ptr = of_list Addr.([UnknownPtr; NullPtr])
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose it's weird because there isn't just a single value that this is_top
returns true for. Probably good to have a comment about it to avoid surprises until we somehow design a more consistent domain where this inconsistency isn't necessary.
val lower_bound : t option (* TODO: unused *) | ||
val upper_bound : t option (* TODO: unused *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those seem a bit strange here. IIRC, IntOpsBase
is the module type we use for single values, not modules, ....
Maybe @jerhard knows what they are intended for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose at some point (maybe pre-bigints) it was necessary to know the min_int
and max_int
for these different types.
@@ -42,7 +42,7 @@ sig | |||
val compare : t -> t -> int | |||
val equal : t -> t -> bool | |||
val hash : t -> int | |||
val top_range : t -> t -> bool | |||
val top_range : t -> t -> bool (* TODO: unused *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, I am not so sure what the intended semantics is here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the implementations, it seems to be for checking if the two arguments are min_int
and max_int
respectively. Again I guess we might've used that pre-bigints to do some special treatment, but that seems specific to intervals anyway.
@@ -51,7 +51,7 @@ sig | |||
val to_int : t -> int | |||
val of_int64 : int64 -> t | |||
val to_int64 : t -> int64 | |||
val of_string : string -> t | |||
val of_string : string -> t (* TODO: unused *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can keep the of_string
, it may be handy sometimes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly yes. I guess this was used when we still parsed the strings from CIL constants for big values.
changes: CompareCIL.change_info | ||
} | ||
|
||
let empty_increment_data ?(server=false) file = { | ||
let empty_increment_data ?(server=false) () = { | ||
server; | ||
old_data = None; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's interesting that the file need not be saved here...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file isn't saved in the incremental data, but with a separate variant into a separate file using Serialize
, so this field was never read from. Actually #357 would probably change this and put the file (along with everything else) into a single record and not have separate files. Depending on the choices taken for #357, it need not be this increment data record that everything goes into, but maybe some outer wrapping record.
@@ -132,6 +132,7 @@ struct | |||
in | |||
fold f xs (empty ()) | |||
|
|||
(* TODO: unused *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we might want to keep this
@@ -31,7 +31,7 @@ sig | |||
val for_all: (key -> value -> bool) -> t -> bool | |||
val map2: (value -> value -> value) -> t -> t -> t | |||
val long_map2: (value -> value -> value) -> t -> t -> t | |||
val merge : (key -> value option -> value option -> value option) -> t -> t -> t | |||
val merge : (key -> value option -> value option -> value option) -> t -> t -> t (* TODO: unused, remove? *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think merge
may also be worth keeping
@@ -105,7 +104,7 @@ struct | |||
(* Map.map (List.map f) m *) | |||
(* since hashes might change we need to rebuild: *) | |||
apply_list (List.map f) m | |||
let filter f m = apply_list (List.filter f) m (* TODO do something better? *) | |||
let filter f m = apply_list (List.filter f) m (* TODO do something better? unused *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's worth keeping
@@ -48,6 +48,7 @@ struct | |||
let elements m = Map.values m |> List.of_enum |> List.flatten | |||
|
|||
(* merge elements in x and y by f *) | |||
(* TODO: unused, remove? *) | |||
let merge op f x y = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also worth keeping in my opinion
Since goblint/gobview#13 is now merged into Gobview, which now depends on changes from this PR, it would be good to now delay this too much since it blocks any other PRs to Gobview as they would only work on this branch of Goblint. Regarding all the "worth keeping" comments, I'd suggest not removing those things now, but leaving the comments so it's immediately apparent if some weird code is used for anything or not. |
Ok, sounds good to me! |
This is the result of me trying out reanalyze on our codebase. Instead of a local unused check based on signatures (which we rarely have) that the OCaml compiler has, this attempts to perform a global dead code analysis.
I manually went through all of its warnings and did one of the following for each one:
TODO