Skip to content

Commit

Permalink
Merge branch 'master' into congruence-hardness-unsound-branches
Browse files Browse the repository at this point in the history
  • Loading branch information
jerhard committed Feb 24, 2025
2 parents 829b2bd + 85aaec9 commit d181989
Show file tree
Hide file tree
Showing 65 changed files with 2,589 additions and 215 deletions.
2 changes: 1 addition & 1 deletion conf/svcomp-ghost.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
"autotune": {
"enabled": true,
"activated": [
"singleThreaded",
"reduceAnalyses",
"mallocWrappers",
"noRecursiveIntervals",
"enums",
Expand Down
2 changes: 1 addition & 1 deletion conf/svcomp-validate.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"autotune": {
"enabled": true,
"activated": [
"singleThreaded",
"reduceAnalyses",
"mallocWrappers",
"noRecursiveIntervals",
"enums",
Expand Down
2 changes: 1 addition & 1 deletion conf/svcomp.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"autotune": {
"enabled": true,
"activated": [
"singleThreaded",
"reduceAnalyses",
"mallocWrappers",
"noRecursiveIntervals",
"enums",
Expand Down
2 changes: 1 addition & 1 deletion conf/svcomp23.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"autotune": {
"enabled": true,
"activated": [
"singleThreaded",
"reduceAnalyses",
"mallocWrappers",
"noRecursiveIntervals",
"enums",
Expand Down
2 changes: 1 addition & 1 deletion conf/svcomp24-validate.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"autotune": {
"enabled": true,
"activated": [
"singleThreaded",
"reduceAnalyses",
"mallocWrappers",
"noRecursiveIntervals",
"enums",
Expand Down
2 changes: 1 addition & 1 deletion conf/svcomp24.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"autotune": {
"enabled": true,
"activated": [
"singleThreaded",
"reduceAnalyses",
"mallocWrappers",
"noRecursiveIntervals",
"enums",
Expand Down
2 changes: 1 addition & 1 deletion conf/svcomp25-validate.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"autotune": {
"enabled": true,
"activated": [
"singleThreaded",
"reduceAnalyses",
"mallocWrappers",
"noRecursiveIntervals",
"enums",
Expand Down
2 changes: 1 addition & 1 deletion conf/svcomp25.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"autotune": {
"enabled": true,
"activated": [
"singleThreaded",
"reduceAnalyses",
"mallocWrappers",
"noRecursiveIntervals",
"enums",
Expand Down
2 changes: 1 addition & 1 deletion conf/svcomp2var.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"autotune": {
"enabled": true,
"activated": [
"singleThreaded",
"reduceAnalyses",
"mallocWrappers",
"noRecursiveIntervals",
"enums",
Expand Down
2 changes: 1 addition & 1 deletion make.sh
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ rule() {
fi
cd webapp && npm install && npm start
;; jar)
echo "Make sure you have the following installed: javac, ant"
echo "Make sure you have the following installed: javac, ant, dot (from graphviz)"
if test ! -e "g2html/build.xml"; then
git submodule update --init --recursive g2html
fi
Expand Down
1 change: 1 addition & 0 deletions scripts/goblint-lib-modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"DefExcDomain", # included in IntDomain
"EnumsDomain", # included in IntDomain
"CongruenceDomain", # included in IntDomain
"BitfieldDomain", #included in IntDomain
"IntDomTuple", # included in IntDomain
"WitnessGhostVar", # included in WitnessGhost

Expand Down
10 changes: 6 additions & 4 deletions src/analyses/base.ml
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,8 @@ struct
let n_offset = iDtoIdx n in
begin match t with
| Some t ->
let (f_offset_bits, _) = bitsOffset t (Field (f, NoOffset)) in
let f_offset = IdxDom.of_int (Cilfacade.ptrdiff_ikind ()) (Z.of_int (f_offset_bits / 8)) in
let f_offset_bytes = Cilfacade.bytesOffsetOnly t (Field (f, NoOffset)) in
let f_offset = IdxDom.of_int (Cilfacade.ptrdiff_ikind ()) (Z.of_int f_offset_bytes) in
begin match IdxDom.(to_bool (eq f_offset (neg n_offset))) with
| Some true -> `NoOffset
| _ -> `Field (f, `Index (n_offset, `NoOffset))
Expand Down Expand Up @@ -624,6 +624,8 @@ struct

let drop_intervalSet = CPA.map (function Int x -> Int (ID.no_intervalSet x) | x -> x )

let drop_bitfield = CPA.map (function Int x -> Int (ID.no_bitfield x) | x -> x )

let context man (fd: fundec) (st: store): store =
let f keep drop_fn (st: store) = if keep then st else { st with cpa = drop_fn st.cpa} in
st |>
Expand All @@ -634,6 +636,7 @@ struct
%> f (ContextUtil.should_keep ~isAttr:GobContext ~keepOption:"ana.base.context.int" ~removeAttr:"base.no-int" ~keepAttr:"base.int" fd) drop_ints
%> f (ContextUtil.should_keep ~isAttr:GobContext ~keepOption:"ana.base.context.interval" ~removeAttr:"base.no-interval" ~keepAttr:"base.interval" fd) drop_interval
%> f (ContextUtil.should_keep ~isAttr:GobContext ~keepOption:"ana.base.context.interval_set" ~removeAttr:"base.no-interval_set" ~keepAttr:"base.interval_set" fd) drop_intervalSet
%> f (ContextUtil.should_keep ~isAttr:GobContext ~keepOption:"ana.base.context.bitfield" ~removeAttr:"base.no-bitfield" ~keepAttr:"base.bitfield" fd) drop_bitfield


let reachable_top_pointers_types man (ps: AD.t) : Queries.TS.t =
Expand Down Expand Up @@ -2286,8 +2289,7 @@ struct
ID.of_int (Cilfacade.ptrdiff_ikind ()) (Z.of_int x)
in
let size_of_type_in_bytes typ =
let typ_size_in_bytes = (bitsSizeOf typ) / 8 in
intdom_of_int typ_size_in_bytes
intdom_of_int (Cilfacade.bytesSizeOf typ)
in
if points_to_heap_only man ptr then
(* Ask for BlobSize from the base address (the second component being set to true) in order to avoid BlobSize giving us bot *)
Expand Down
35 changes: 27 additions & 8 deletions src/analyses/baseInvariant.ml
Original file line number Diff line number Diff line change
Expand Up @@ -395,27 +395,46 @@ struct
| Le, Some false -> meet_bin (ID.starting ikind (Z.succ l2)) (ID.ending ikind (Z.pred u1))
| _, _ -> a, b)
| _ -> a, b)
| BOr | BXor as op->
if M.tracing then M.tracel "inv" "Unhandled operator %a" d_binop op;
| BOr ->
(* Be careful: inv_exp performs a meet on both arguments of the BOr / BXor. *)
a, b
if PrecisionUtil.get_bitfield () then
(* refinement based on the following idea: bit set to one in c and set to zero in b must be one in a and bit set to zero in c must be zero in a too (analogously for b) *)
let ((az, ao), (bz, bo)) = BitfieldDomain.Bitfield.refine_bor (ID.to_bitfield ikind a) (ID.to_bitfield ikind b) (ID.to_bitfield ikind c) in
ID.meet a (ID.of_bitfield ikind (az, ao)), ID.meet b (ID.of_bitfield ikind (bz, bo))
else
(if M.tracing then M.tracel "inv" "Unhandled operator %a" d_binop op;
(* Be careful: inv_exp performs a meet on both arguments of the BOr / BXor. *)
(a, b)
)
| BXor ->
(* Be careful: inv_exp performs a meet on both arguments of the BOr / BXor. *)
meet_com ID.logxor
| LAnd ->
if ID.to_bool c = Some true then
meet_bin c c
else
a, b
| BAnd as op ->
| BAnd ->
(* we only attempt to refine a here *)
let b_int = ID.to_int b in
let a =
match ID.to_int b with
match b_int with
| Some x when Z.equal x Z.one ->
(match ID.to_bool c with
| Some true -> ID.meet a (ID.of_congruence ikind (Z.one, Z.of_int 2))
| Some false -> ID.meet a (ID.of_congruence ikind (Z.zero, Z.of_int 2))
| None -> if M.tracing then M.tracel "inv" "Unhandled case for operator x %a 1 = %a" d_binop op ID.pretty c; a)
| _ -> if M.tracing then M.tracel "inv" "Unhandled case for operator x %a %a = %a" d_binop op ID.pretty b ID.pretty c; a
| None -> a)
| _ -> a
in
a, b
if PrecisionUtil.get_bitfield () then
(* refinement based on the following idea: bit set to zero in c and set to one in b must be zero in a and bit set to one in c must be one in a too (analogously for b) *)
let ((az, ao), (bz, bo)) = BitfieldDomain.Bitfield.refine_band (ID.to_bitfield ikind a) (ID.to_bitfield ikind b) (ID.to_bitfield ikind c) in
ID.meet a (ID.of_bitfield ikind (az, ao)), ID.meet b (ID.of_bitfield ikind (bz, bo))
else if b_int = None then
(if M.tracing then M.tracel "inv" "Unhandled operator %a" d_binop op;
(a, b)
)
else a, b
| op ->
if M.tracing then M.tracel "inv" "Unhandled operator %a" d_binop op;
a, b
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/memLeak.ml
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ struct
(* Upon a call to the "Abort" special function in the multi-threaded case, we give up and conservatively warn *)
warn_for_multi_threaded_due_to_abort man;
state
| Assert { exp; _ } ->
| Assert { exp; refine = true; _ } ->
begin match man.ask (Queries.EvalInt exp) with
| a when Queries.ID.is_bot a -> M.warn ~category:Assert "assert expression %a is bottom" d_exp exp
| a ->
Expand Down
15 changes: 7 additions & 8 deletions src/analyses/memOutOfBounds.ml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ struct
ID.of_int (Cilfacade.ptrdiff_ikind ()) (Z.of_int x)

let size_of_type_in_bytes typ =
let typ_size_in_bytes = (bitsSizeOf typ) / 8 in
intdom_of_int typ_size_in_bytes
intdom_of_int (Cilfacade.bytesSizeOf typ)

let rec exp_contains_a_ptr (exp:exp) =
match exp with
Expand Down Expand Up @@ -127,7 +126,7 @@ struct
`Top)

let get_ptr_deref_type ptr_typ =
match ptr_typ with
match Cil.unrollType ptr_typ with
| TPtr (t, _) -> Some t
| _ -> None

Expand All @@ -149,8 +148,8 @@ struct
| `NoOffset -> intdom_of_int 0
| `Field (field, o) ->
let field_as_offset = Field (field, NoOffset) in
let bits_offset, _size = GoblintCil.bitsOffset (TComp (field.fcomp, [])) field_as_offset in
let bytes_offset = intdom_of_int (bits_offset / 8) in
let bytes_offset = Cilfacade.bytesOffsetOnly (TComp (field.fcomp, [])) field_as_offset in
let bytes_offset = intdom_of_int bytes_offset in
let remaining_offset = offs_to_idx field.ftype o in
begin
try ID.add bytes_offset remaining_offset
Expand All @@ -175,7 +174,7 @@ struct
`Index (ID.top (), convert_offset ofs)
| Index (exp, ofs) ->
let i = match man.ask (Queries.EvalInt exp) with
| `Lifted x -> x
| `Lifted x -> ID.cast_to (Cilfacade.ptrdiff_ikind ()) x
| _ -> ID.top_of @@ Cilfacade.ptrdiff_ikind ()
in
`Index (i, convert_offset ofs)
Expand Down Expand Up @@ -279,10 +278,10 @@ struct
M.warn "Size of lval dereference expression %a is bot. Out-of-bounds memory access may occur" d_exp e)
| `Lifted es ->
let casted_es = ID.cast_to (Cilfacade.ptrdiff_ikind ()) es in
let one = intdom_of_int 1 in
let casted_es = ID.sub casted_es one in
let casted_offs = ID.cast_to (Cilfacade.ptrdiff_ikind ()) offs_intdom in
let ptr_size_lt_offs =
let one = intdom_of_int 1 in
let casted_es = ID.sub casted_es one in
begin try ID.lt casted_es casted_offs
with IntDomain.ArithmeticOnIntegerBot _ -> ID.bot_of @@ Cilfacade.ptrdiff_ikind ()
end
Expand Down
61 changes: 30 additions & 31 deletions src/autoTune.ml
Original file line number Diff line number Diff line change
Expand Up @@ -206,29 +206,31 @@ let hasFunction pred =
calls.calledBy |> FunctionCallMap.exists (fun var _ -> relevant_static var) ||
calls.dynamicallyCalled |> FunctionSet.exists relevant_dynamic

let disableAnalyses anas =
List.iter (GobConfig.set_auto "ana.activated[-]") anas
let disableAnalyses reason analyses =
Logs.info "%s -> disabling analyses: \"%s\"" reason (String.concat ", " analyses);
List.iter (GobConfig.set_auto "ana.activated[-]") analyses

let enableAnalyses anas =
List.iter (GobConfig.set_auto "ana.activated[+]") anas
let enableAnalyses reason description analyses =
Logs.info "%s -> enabling %s: \"%s\"" reason description (String.concat ", " analyses);
List.iter (GobConfig.set_auto "ana.activated[+]") analyses

(*If only one thread is used in the program, we can disable most thread analyses*)
(*The exceptions are analyses that are depended on by others: base -> mutex -> mutexEvents, access; termination -> threadflag *)
(*escape is also still enabled, because otherwise we get a warning*)
(*does not consider dynamic calls!*)
let notNeccessaryRaceAnalyses = ["race"; "symb_locks"; "region"]
let notNeccessaryThreadAnalyses = notNeccessaryRaceAnalyses @ ["deadlock"; "maylocks"; "thread"; "threadid"; "threadJoins"; "threadreturn"; "mhp"; "pthreadMutexType"]

let notNeccessaryThreadAnalyses = ["race"; "deadlock"; "maylocks"; "symb_locks"; "thread"; "threadid"; "threadJoins"; "threadreturn"; "mhp"; "region"; "pthreadMutexType"]
let reduceThreadAnalyses () =
let hasSpec spec = List.mem spec (Svcomp.Specification.of_option ())

let reduceAnalyses () =
let isThreadCreate (desc: LibraryDesc.t) args =
match desc.special args with
| LibraryDesc.ThreadCreate _ -> true
| _ -> LibraryDesc.Accesses.find_kind desc.accs Spawn args <> []
in
let hasThreadCreate = hasFunction isThreadCreate in
if not @@ hasThreadCreate then (
Logs.info "no thread creation -> disabling thread analyses \"%s\"" (String.concat ", " notNeccessaryThreadAnalyses);
disableAnalyses notNeccessaryThreadAnalyses;
)
if not hasThreadCreate then disableAnalyses "no thread creation" notNeccessaryThreadAnalyses

let focusOnMemSafetySpecification (spec: Svcomp.Specification.t) =
match spec with
Expand All @@ -247,8 +249,7 @@ let focusOnTermination (spec: Svcomp.Specification.t) =
match spec with
| Termination ->
let terminationAnas = ["threadflag"; "apron"] in
Logs.info "Specification: Termination -> enabling termination analyses \"%s\"" (String.concat ", " terminationAnas);
enableAnalyses terminationAnas;
enableAnalyses "Specification: Termination" "termination analyses" terminationAnas;
set_string "sem.int.signed_overflow" "assume_none";
set_bool "ana.int.interval" true;
set_string "ana.apron.domain" "polyhedra"; (* TODO: Needed? *)
Expand All @@ -258,16 +259,16 @@ let focusOnTermination (spec: Svcomp.Specification.t) =
let focusOnTermination () =
List.iter focusOnTermination (Svcomp.Specification.of_option ())

let concurrencySafety (spec: Svcomp.Specification.t) =
match spec with
| NoDataRace -> (*enable all thread analyses*)
Logs.info "Specification: NoDataRace -> enabling thread analyses \"%s\"" (String.concat ", " notNeccessaryThreadAnalyses);
enableAnalyses notNeccessaryThreadAnalyses;
| _ -> ()
let focusOnConcurrencySafety () =
if hasSpec SvcompSpec.NoDataRace then
(*enable all thread analyses*)
(* TODO: what's the exact relation between thread analyses enabled in conf, the ones we disable in reduceAnalyses and the ones we enable here? *)
enableAnalyses "Specification: NoDataRace" "thread analyses" notNeccessaryThreadAnalyses
else
disableAnalyses "NoDataRace property is not in spec" notNeccessaryRaceAnalyses

let noOverflows (spec: Svcomp.Specification.t) =
match spec with
| NoOverflow ->
let focusOnNoOverflows () =
if hasSpec SvcompSpec.NoOverflow then (
(*We focus on integer analysis*)
set_bool "ana.int.def_exc" true;
begin
Expand All @@ -276,10 +277,7 @@ let noOverflows (spec: Svcomp.Specification.t) =
set_int "ana.malloc.unique_address_count" 1
with Found -> set_int "ana.malloc.unique_address_count" 0;
end
| _ -> ()

let focusOn (f : SvcompSpec.t -> unit) =
List.iter f (Svcomp.Specification.of_option ())
)

(*Detect enumerations and enable the "ana.int.enums" option*)
exception EnumFound
Expand Down Expand Up @@ -492,8 +490,7 @@ let activateTmpSpecialAnalysis () =
in
let hasMathFunctions = hasFunction isMathFun in
if hasMathFunctions then (
Logs.info "math function -> enabling tmpSpecial analysis and floating-point domain";
enableAnalyses ["tmpSpecial"];
enableAnalyses "Math function" "tmpSpecial analysis and floating-point domain" ["tmpSpecial"];
set_bool "ana.float.interval" true;
)

Expand Down Expand Up @@ -546,15 +543,17 @@ let chooseConfig file =
if isActivated "mallocWrappers" then
findMallocWrappers ();

if isActivated "concurrencySafetySpecification" then focusOn concurrencySafety;
if isActivated "concurrencySafetySpecification" then
focusOnConcurrencySafety ();

if isActivated "noOverflows" then focusOn noOverflows;
if isActivated "noOverflows" then
focusOnNoOverflows ();

if isActivated "enums" && hasEnums file then
set_bool "ana.int.enums" true;

if isActivated "singleThreaded" then
reduceThreadAnalyses ();
if isActivated "reduceAnalyses" then
reduceAnalyses ();

if isActivated "arrayDomain" then
selectArrayDomains file;
Expand Down
Loading

0 comments on commit d181989

Please sign in to comment.