Skip to content

Commit 811c183

Browse files
Hotfix for #1421
1 parent a11f713 commit 811c183

File tree

2 files changed

+59
-35
lines changed

2 files changed

+59
-35
lines changed

src/analyses/base.ml

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -979,41 +979,45 @@ struct
979979
(* Evaluate structurally using base at first. *)
980980
let a1 = eval_rv ~ctx st e1 in
981981
let a2 = eval_rv ~ctx st e2 in
982-
let t1 = Option.default_delayed (fun () -> Cilfacade.typeOf e1) t1 in
983-
let t2 = Option.default_delayed (fun () -> Cilfacade.typeOf e2) t2 in
984-
let r = evalbinop_base ~ctx op t1 a1 t2 a2 t in
985-
if Cil.isIntegralType t then (
986-
match r with
987-
| Int i when ID.to_int i <> None -> r (* Avoid fallback, cannot become any more precise. *)
988-
| _ ->
989-
(* Fallback to MustBeEqual query, could get extra precision from exprelation/var_eq. *)
990-
let must_be_equal () =
991-
let r = Q.must_be_equal (Analyses.ask_of_ctx ctx) e1 e2 in
992-
if M.tracing then M.tracel "query" "MustBeEqual (%a, %a) = %b" d_exp e1 d_exp e2 r;
993-
r
994-
in
995-
match op with
996-
| MinusA when must_be_equal () ->
997-
let ik = Cilfacade.get_ikind t in
998-
Int (ID.of_int ik Z.zero)
999-
| MinusPI (* TODO: untested *)
1000-
| MinusPP when must_be_equal () ->
1001-
let ik = Cilfacade.ptrdiff_ikind () in
1002-
Int (ID.of_int ik Z.zero)
1003-
(* Eq case is unnecessary: Q.must_be_equal reconstructs BinOp (Eq, _, _, _) and repeats EvalInt query for that, yielding a top from query cycle and never being must equal *)
1004-
| Le
1005-
| Ge when must_be_equal () ->
1006-
let ik = Cilfacade.get_ikind t in
1007-
Int (ID.of_bool ik true)
1008-
| Ne
1009-
| Lt
1010-
| Gt when must_be_equal () ->
1011-
let ik = Cilfacade.get_ikind t in
1012-
Int (ID.of_bool ik false)
1013-
| _ -> r (* Fallback didn't help. *)
1014-
)
1015-
else
1016-
r (* Avoid fallback, above cases are for ints only. *)
982+
try
983+
let t1 = Option.default_delayed (fun () -> Cilfacade.typeOf e1) t1 in
984+
let t2 = Option.default_delayed (fun () -> Cilfacade.typeOf e2) t2 in
985+
let r = evalbinop_base ~ctx op t1 a1 t2 a2 t in
986+
if Cil.isIntegralType t then (
987+
match r with
988+
| Int i when ID.to_int i <> None -> r (* Avoid fallback, cannot become any more precise. *)
989+
| _ ->
990+
(* Fallback to MustBeEqual query, could get extra precision from exprelation/var_eq. *)
991+
let must_be_equal () =
992+
let r = Q.must_be_equal (Analyses.ask_of_ctx ctx) e1 e2 in
993+
if M.tracing then M.tracel "query" "MustBeEqual (%a, %a) = %b" d_exp e1 d_exp e2 r;
994+
r
995+
in
996+
match op with
997+
| MinusA when must_be_equal () ->
998+
let ik = Cilfacade.get_ikind t in
999+
Int (ID.of_int ik Z.zero)
1000+
| MinusPI (* TODO: untested *)
1001+
| MinusPP when must_be_equal () ->
1002+
let ik = Cilfacade.ptrdiff_ikind () in
1003+
Int (ID.of_int ik Z.zero)
1004+
(* Eq case is unnecessary: Q.must_be_equal reconstructs BinOp (Eq, _, _, _) and repeats EvalInt query for that, yielding a top from query cycle and never being must equal *)
1005+
| Le
1006+
| Ge when must_be_equal () ->
1007+
let ik = Cilfacade.get_ikind t in
1008+
Int (ID.of_bool ik true)
1009+
| Ne
1010+
| Lt
1011+
| Gt when must_be_equal () ->
1012+
let ik = Cilfacade.get_ikind t in
1013+
Int (ID.of_bool ik false)
1014+
| _ -> r (* Fallback didn't help. *)
1015+
)
1016+
else
1017+
r (* Avoid fallback, above cases are for ints only. *)
1018+
with Cilfacade.TypeOfError _ ->
1019+
(* Emit top value of corresponding type when there are issues *)
1020+
VD.top_value t
10171021

10181022
(* A hackish evaluation of expressions that should immediately yield an
10191023
* address, e.g. when calling functions. *)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Should not crash (issue 1421)
2+
#include<pthread.h>
3+
struct a {
4+
pthread_mutex_t b;
5+
};
6+
struct c {
7+
struct a *conn;
8+
};
9+
10+
int main() {
11+
int x;
12+
struct a str = {0};
13+
struct c axel = {0};
14+
axel.conn = &str;
15+
pthread_mutex_t* ptr = &((axel.conn + 0)->b);
16+
x = 4;
17+
pthread_mutex_lock(ptr);
18+
pthread_mutex_unlock(ptr);
19+
pthread_mutex_lock(&((axel.conn + 0)->b));
20+
}

0 commit comments

Comments
 (0)