Skip to content

Commit b2a3242

Browse files
committed
disable cachedqueries to fix no_overflow computation
1 parent ccc8a54 commit b2a3242

File tree

5 files changed

+19
-52
lines changed

5 files changed

+19
-52
lines changed

src/analyses/apron/relationAnalysis.apron.ml

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -174,39 +174,12 @@ struct
174174
(** An extended overflow handling inside relationAnalysis for expression assignments when overflows are assumed to occur.
175175
Since affine equalities can only keep track of integer bounds of expressions evaluating to definite constants, we now query the integer bounds information for expressions from other analysis.
176176
If an analysis returns bounds that are unequal to min and max of ikind , we can exclude the possibility that an overflow occurs and the abstract effect of the expression assignment can be used, i.e. we do not have to set the variable's value to top. *)
177-
178-
let exp_does_not_contain_top (ask: Queries.ask) exp =
179-
let exp_not_top e = match Cilfacade.get_ikind_exp exp with
180-
| exception Invalid_argument _
181-
| exception Cilfacade.TypeOfError _ -> false
182-
| ik -> let r = not (Queries.ID.is_top_of ik (ask.f (EvalInt e))) in
183-
if M.tracing then M.trace "no_o" "exp_not_top %a %a %a-> %b \n" d_exp exp d_ikind ik (ValueDomainQueries.ID.pretty) (ask.f (EvalInt e)) r;
184-
r
185-
in
186-
let rec exp_contais_no_top e =
187-
if M.tracing then M.trace "no_o" "exp_contais_no_top %a\n" d_exp e;
188-
match Cilfacade.get_ikind_exp e with
189-
| exception Invalid_argument _ -> false (* TODO: why this? *)
190-
| exception Cilfacade.TypeOfError _ -> false
191-
| ik ->
192-
let subexp_contains_no_top = match e with
193-
| BinOp (_, e1, e2, _) -> exp_contais_no_top e1 && exp_contais_no_top e2
194-
| _ -> true
195-
in
196-
if subexp_contains_no_top then
197-
let r = exp_not_top e in
198-
r
199-
else
200-
false
201-
in
202-
exp_contais_no_top exp
203-
204177
let no_overflow (ask: Queries.ask) exp =
205178
match Cilfacade.get_ikind_exp exp with
206179
| exception Invalid_argument _ -> false (* TODO: why this? *)
207180
| exception Cilfacade.TypeOfError _ -> false
208181
| ik ->
209-
let r = exp_does_not_contain_top ask exp in
182+
let r = ask.f (MayOverflow exp) in
210183
if M.tracing then M.trace "no_o" "no_o exp: %a %a -> %b \n" d_exp exp d_ikind ik r;
211184
r
212185

@@ -613,23 +586,15 @@ struct
613586
if M.tracing then M.tracel "combine" "relation remove vars: %a\n" (docList (fun v -> Pretty.text (Apron.Var.to_string v))) arg_vars;
614587
RD.remove_vars_with new_fun_rel arg_vars; (* fine to remove arg vars that also exist in caller because unify from new_rel adds them back with proper constraints *)
615588
let tainted = f_ask.f Queries.MayBeTainted in
616-
if M.tracing then M.trace "combine" "Var tainted: %a\n" (Queries.AD.pretty ) tainted;
617589
let tainted_vars = TaintPartialContexts.conv_varset tainted in
618-
if M.tracing then M.trace "combine" "";
619590
let new_rel = RD.keep_filter st.rel (fun var ->
620591
match RV.find_metadata var with
621592
| Some (Local _) when not (pass_to_callee fundec any_local_reachable var) -> true (* keep caller locals, provided they were not passed to the function *)
622593
| Some (Arg _) -> true (* keep caller args *)
623594
| Some (Local v) when AllocSize.mem_varinfo v || PointerMap.mem_varinfo v || ArrayMap.mem_varinfo v -> true (* keep ghost Variables already filtered out in return *)
624-
| Some ((Local _ | Global _)) when not (RD.mem_var new_fun_rel var) ->
625-
if M.tracing then M.trace "combine" "remove no record %a\n" (docOpt (CilType.Varinfo.pretty())) (RV.to_cil_varinfo var);
626-
false (* remove locals and globals, for which no record exists in the new_fun_apr *)
627-
| Some ((Local v | Global v)) when not (TaintPartialContexts.VS.mem v tainted_vars) ->
628-
if M.tracing then M.trace "combine" "remove tainted %a\n" CilType.Varinfo.pretty v;
629-
true (* keep locals and globals, which have not been touched by the call *)
630-
| v ->
631-
if M.tracing then M.trace "combine" "remove else %s\n" (match v with |None -> "none" | Some v -> (VM.var_name) v );
632-
false (* remove everything else (globals, global privs, reachable things from the caller) *)
595+
| Some ((Local _ | Global _)) when not (RD.mem_var new_fun_rel var) -> false (* remove locals and globals, for which no record exists in the new_fun_apr *)
596+
| Some ((Local v | Global v)) when not (TaintPartialContexts.VS.mem v tainted_vars) -> true (* keep locals and globals, which have not been touched by the call *)
597+
| v -> false (* remove everything else (globals, global privs, reachable things from the caller) *)
633598
)
634599
in
635600
let unify_rel = RD.unify new_rel new_fun_rel in (* TODO: unify_with *)

src/analyses/base.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,10 +1396,12 @@ struct
13961396
let g: V.t = Obj.obj g in
13971397
query_invariant_global ctx g
13981398
| Q.MayOverflow e ->
1399+
MCP.lookUpCache := false;
13991400
IntDomain.local_no_overflow := true;
1400-
if M.tracing then M.trace "apron" "exp %a\n" d_exp e;
1401+
if M.tracing then M.trace "no_ov" "exp %a\n" d_exp e;
14011402
ignore(query_evalint ~ctx ctx.local e);
1402-
!IntDomain.local_no_overflow ;
1403+
MCP.lookUpCache := true;
1404+
!IntDomain.local_no_overflow
14031405
| _ -> Q.Result.top q
14041406

14051407
let update_variable variable typ value cpa =

src/analyses/mCP.ml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -180,13 +180,13 @@ struct
180180
let octx = ctx in
181181
let ctx_with_local ctx local' =
182182
(* let rec ctx' =
183-
{ ctx with
183+
{ ctx with
184184
local = local';
185185
ask = ask
186-
}
187-
and ask q = query ctx' q
188-
in
189-
ctx' *)
186+
}
187+
and ask q = query ctx' q
188+
in
189+
ctx' *)
190190
{ctx with local = local'}
191191
in
192192
let do_emit ctx = function
@@ -249,10 +249,10 @@ struct
249249
let anyq = Queries.Any q in
250250
if M.tracing then M.traceli "query" "query %a\n" Queries.Any.pretty anyq;
251251
let r = match Queries.Hashtbl.find_option querycache anyq with
252-
| Some r ->
252+
| Some r when !lookUpCache ->
253253
if M.tracing then M.trace "query" "cached\n";
254254
Obj.obj r
255-
| None ->
255+
| _ ->
256256
let module Result = (val Queries.Result.lattice q) in
257257
if Queries.Set.mem anyq asked then (
258258
if M.tracing then M.trace "query" "cycle\n";

src/analyses/mCPRegistry.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ let activated_ctx_sens: (int * spec_modules) list ref = ref []
2121
let activated_path_sens: (int * spec_modules) list ref = ref []
2222
let registered: (int, spec_modules) Hashtbl.t = Hashtbl.create 100
2323
let registered_name: (string, int) Hashtbl.t = Hashtbl.create 100
24+
let lookUpCache = ref(true) (*disable cachedQueries to compute no_overflow flag in apron*)
2425

2526
let register_analysis =
2627
let count = ref 0 in

src/cdomain/value/cdomains/intDomain.ml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,10 @@ type overflow_info = { overflow: bool; underflow: bool;}
7878
let local_no_overflow = ref true
7979
let set_overflow_flag ~cast ~underflow ~overflow ik =
8080
let signed = Cil.isSigned ik in
81-
if signed && not cast then
82-
(local_no_overflow := false;
83-
if !AnalysisState.postsolving then
84-
AnalysisState.svcomp_may_overflow := true);
81+
if !AnalysisState.postsolving && signed && not cast then
82+
AnalysisState.svcomp_may_overflow := true;
8583
let sign = if signed then "Signed" else "Unsigned" in
84+
local_no_overflow := false;
8685
match underflow, overflow with
8786
| true, true ->
8887
M.warn ~category:M.Category.Integer.overflow ~tags:[CWE 190; CWE 191] "%s integer overflow and underflow" sign

0 commit comments

Comments
 (0)