From b8bf69376ab74b4ae25845de51b90cf4896a33cd Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 12 Apr 2026 07:17:38 +0000
Subject: [PATCH 1/3] Initial plan
From ed977a3d0125a1a24b5b8965eb3ea275701a4850 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 12 Apr 2026 08:00:13 +0000
Subject: [PATCH 2/3] Add pp implementations to modules implementing
Printable.S
Add pp to modules that implement Printable.S without SimplePretty/SimpleShow/SimpleFormat:
- FlagHelper: derive pp from show
- partitionDomain: Make and SetSet get pp from show
- ResultType2: derive pp from overridden show
- creationLockset A: derive pp from show
- mCPRegistry DomListPrintable/DomVariantPrintable: derive pp from show
- basetype Variables/RawStrings/CilStmt: derive pp from show
- controlSpecC: derive pp from show
Add pp_trace to VarType signature and implementations:
- constrSys VarType: add val pp_trace
- constrSys Var2: implement pp_trace via GobPretty.sprint
- analyses VarF: implement pp_trace via GobPretty.sprint
- analyses GVarF/GVarFC: pp_trace = pp
- node: add pp_trace using show
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: michael-schwarz <13812333+michael-schwarz@users.noreply.github.com>
---
src/analyses/creationLockset.ml | 1 +
src/analyses/mCPRegistry.ml | 4 ++++
src/common/cdomains/basetype.ml | 3 +++
src/common/domains/printable.ml | 33 ++++++++++++++++++++++++++++
src/common/framework/controlSpecC.ml | 1 +
src/common/framework/node.ml | 2 ++
src/common/util/gobFormat.ml | 4 ++++
src/constraint/constrSys.ml | 3 +++
src/domain/flagHelper.ml | 1 +
src/domain/hoareDomain.ml | 5 +++++
src/domain/mapDomain.ml | 33 ++++++++++++++++++++++++++++
src/domain/partitionDomain.ml | 2 ++
src/domain/setDomain.ml | 14 ++++++++++++
src/framework/analyses.ml | 4 ++++
src/framework/analysisResult.ml | 1 +
src/util/std/gobFpath.ml | 2 ++
16 files changed, 113 insertions(+)
diff --git a/src/analyses/creationLockset.ml b/src/analyses/creationLockset.ml
index 61fc797585..905614ca81 100644
--- a/src/analyses/creationLockset.ml
+++ b/src/analyses/creationLockset.ml
@@ -140,6 +140,7 @@ module Spec = struct
(* TID and Lockset components are directly queried from other analyses and already are printed by them *)
let pretty () (_, _, cl) = G.pretty () cl
let show (_, _, cl) = G.show cl
+ let pp ppf x = Format.pp_print_string ppf (show x)
let to_yojson (_, _, cl) = G.to_yojson cl
let printXml f (_, _, cl) = G.printXml f cl
diff --git a/src/analyses/mCPRegistry.ml b/src/analyses/mCPRegistry.ml
index 05519dbb62..09975b5027 100644
--- a/src/analyses/mCPRegistry.ml
+++ b/src/analyses/mCPRegistry.ml
@@ -169,6 +169,8 @@ struct
in
IO.to_string (List.print ~first:"[" ~last:"]" ~sep:", " String.print) (rev xs)
+ let pp ppf x = Format.pp_print_string ppf (show x)
+
let to_yojson xs =
let f a n (module S : Printable.S) x =
let name = find_spec_name n in
@@ -246,6 +248,8 @@ struct
analysis_name ^ ":" ^ S.show (Obj.obj x)
)
+ let pp ppf x = Format.pp_print_string ppf (show x)
+
let to_yojson x =
`Assoc [
unop_map (fun n (module S: Printable.S) x ->
diff --git a/src/common/cdomains/basetype.ml b/src/common/cdomains/basetype.ml
index 5ec9b22b44..fa86fbc50e 100644
--- a/src/common/cdomains/basetype.ml
+++ b/src/common/cdomains/basetype.ml
@@ -11,6 +11,7 @@ struct
let description = RichVarinfo.BiVarinfoMap.Collection.describe_varinfo x in
"(" ^ x.vname ^ ", " ^ description ^ ")"
else x.vname
+ let pp ppf x = Format.pp_print_string ppf (show x)
let pretty () x = Pretty.text (show x)
type group = Global | Local | Parameter | Temp [@@deriving ord, show { with_path = false }]
let to_group = function
@@ -28,6 +29,7 @@ struct
open Pretty
type t = string [@@deriving eq, ord, hash, to_yojson]
let show x = "\"" ^ x ^ "\""
+ let pp ppf x = Format.pp_print_string ppf (show x)
let pretty () x = text (show x)
let name () = "raw strings"
let printXml f x = BatPrintf.fprintf f "\n\n%s\n\n\n" (XmlUtil.escape (show x))
@@ -125,6 +127,7 @@ module CilStmt: Printable.S with type t = stmt =
struct
include CilType.Stmt
let show x = ""
+ let pp ppf x = Format.pp_print_string ppf (show x)
let pretty = Cilfacade.stmt_pretty_short
let name () = "expressions"
diff --git a/src/common/domains/printable.ml b/src/common/domains/printable.ml
index 45a66ea336..3d5bfe4eeb 100644
--- a/src/common/domains/printable.ml
+++ b/src/common/domains/printable.ml
@@ -12,6 +12,7 @@ sig
val compare: t -> t -> int
val show: t -> string
val pretty: unit -> t -> doc
+ val pp: Format.formatter -> t -> unit
(* These two lets us reuse the short function, and allows some overriding
* possibilities. *)
val printXml : 'a BatInnerIO.output -> t -> unit
@@ -35,6 +36,7 @@ struct
type t = | [@@deriving eq, ord, hash]
let show (x: t) = match x with _ -> .
let pretty () (x: t) = match x with _ -> .
+ let pp _ (x: t) = match x with _ -> .
let printXml _ (x: t) = match x with _ -> .
let name () = "empty"
let to_yojson (x: t) = match x with _ -> .
@@ -71,6 +73,7 @@ end
module SimpleShow (P: Showable) =
struct
let pretty () x = text (P.show x)
+ let pp ppf x = Format.pp_print_string ppf (P.show x)
let printXml f x = BatPrintf.fprintf f "\n\n%s\n\n\n" (XmlUtil.escape (P.show x))
let to_yojson x = `String (P.show x)
end
@@ -84,6 +87,7 @@ end
module SimplePretty (P: Prettyable) =
struct
let show x = GobPretty.sprint P.pretty x
+ let pp ppf x = Format.pp_print_string ppf (show x)
let printXml f x = BatPrintf.fprintf f "\n\n%s\n\n\n" (XmlUtil.escape (show x))
let to_yojson x = `String (show x)
end
@@ -96,6 +100,7 @@ end
module SimpleFormat (P: Formatable) =
struct
+ let pp = P.pp
let show x = GobFormat.asprint P.pp x
let pretty () x = text (show x)
let printXml f x = BatPrintf.fprintf f "\n\n%s\n\n\n" (XmlUtil.escape (show x))
@@ -109,6 +114,7 @@ struct
type t = unit [@@deriving eq, ord, hash]
include StdLeaf
let pretty () _ = text N.name
+ let pp ppf _ = Format.pp_print_string ppf N.name
let show _ = N.name
let name () = "Unit"
let printXml f () = BatPrintf.fprintf f "\n\n%s\n\n\n" (XmlUtil.escape N.name)
@@ -132,6 +138,7 @@ struct
let show = lift_f Base.show
let pretty () = lift_f (Base.pretty ())
+ let pp ppf = lift_f (Base.pp ppf)
(* Debug printing with tags *)
(* let pretty () x = Pretty.dprintf "%a[%d,%d]" Base.pretty x.BatHashcons.obj x.BatHashcons.tag x.BatHashcons.hcode
@@ -189,6 +196,7 @@ struct
let show = lift_f Base.show
let pretty () = lift_f (Base.pretty ())
+ let pp ppf = lift_f (Base.pp ppf)
let printXml f = lift_f (Base.printXml f)
let to_yojson = lift_f (Base.to_yojson)
@@ -220,6 +228,8 @@ struct
else
Base.show x
+ let pp ppf x = Format.pp_print_string ppf (show x)
+
let printXml f x =
if Conf.expand then
BatPrintf.fprintf f "\n\n" (Base.name ()) Base.printXml x
@@ -268,6 +278,8 @@ struct
| `Bot -> bot_name
| `Top -> top_name
+ let pp ppf x = Format.pp_print_string ppf (show x)
+
let pretty () (state:t) =
match state with
| `Lifted n -> Base.pretty () n
@@ -329,6 +341,8 @@ struct
| `Left n -> Base1.show n
| `Right n -> Base2.show n
+ let pp ppf x = Format.pp_print_string ppf (show x)
+
let name () = "either " ^ Base1.name () ^ " or " ^ Base2.name ()
let printXml f = function
| `Left x -> Base1.printXml f x
@@ -374,6 +388,8 @@ struct
| `Middle n -> Base2.show n
| `Right n -> Base3.show n
+ let pp ppf x = Format.pp_print_string ppf (show x)
+
let name () = "either " ^ Base1.name () ^ " or " ^ Base2.name () ^ " or " ^ Base3.name ()
let printXml f = function
| `Left x -> Base1.printXml f x
@@ -408,6 +424,8 @@ struct
| None -> N.name
| Some n -> Base.show n
+ let pp ppf x = Format.pp_print_string ppf (show x)
+
let name () = Base.name () ^ " option"
let printXml f = function
| None -> BatPrintf.fprintf f "\n\n%s\n\n\n" (XmlUtil.escape N.name)
@@ -451,6 +469,8 @@ struct
| `Bot -> bot_name
| `Top -> top_name
+ let pp ppf x = Format.pp_print_string ppf (show x)
+
let relift x = match x with
| `Lifted1 n -> `Lifted1 (Base1.relift n)
| `Lifted2 n -> `Lifted2 (Base2.relift n)
@@ -512,6 +532,8 @@ struct
else
text (show (x,y))
+ let pp ppf x = Format.pp_print_string ppf (show x)
+
let printXml f (x,y) =
BatPrintf.fprintf f "\n\n\n" (XmlUtil.escape (Base1.name ())) Base1.printXml x (XmlUtil.escape (Base2.name ())) Base2.printXml y
@@ -560,6 +582,8 @@ struct
++ unalign
++ text ")"
+ let pp ppf x = Format.pp_print_string ppf (show x)
+
let printXml f (x,y,z) =
BatPrintf.fprintf f "\n\n\n" (XmlUtil.escape (Base1.name ())) Base1.printXml x (XmlUtil.escape (Base2.name ())) Base2.printXml y (XmlUtil.escape (Base3.name ())) Base3.printXml z
@@ -579,6 +603,7 @@ struct
let show x = "[" ^ (BatDeque.fold_right (fun a acc -> Base.show a ^ ", " ^ acc) x "]")
let pretty () x = text (show x)
+ let pp ppf x = Format.pp_print_string ppf (show x)
let name () = Base.name () ^ "queue"
let relift x = BatDeque.map Base.relift x
@@ -618,6 +643,7 @@ struct
"[" ^ (String.concat ", " elems) ^ "]"
let pretty () x = text (show x)
+ let pp ppf x = Format.pp_print_string ppf (show x)
let relift x = List.map Base.relift x
@@ -647,6 +673,7 @@ struct
let show x = P.names x
let pretty () x = text (show x)
+ let pp ppf x = Format.pp_print_string ppf (show x)
let printXml f x = BatPrintf.fprintf f "\n\n%s\n\n\n" (P.names x)
let to_yojson x = `String (P.names x)
@@ -665,6 +692,8 @@ struct
| `Lifted n -> Base.show n
| `Bot -> "bot of " ^ (Base.name ())
+ let pp ppf x = Format.pp_print_string ppf (show x)
+
let pretty () (state:t) =
match state with
| `Lifted n -> Base.pretty () n
@@ -696,6 +725,8 @@ struct
| `Lifted n -> Base.show n
| `Top -> "top of " ^ (Base.name ())
+ let pp ppf x = Format.pp_print_string ppf (show x)
+
let pretty () (state:t) =
match state with
| `Lifted n -> Base.pretty () n
@@ -733,6 +764,7 @@ struct
type t = string [@@deriving eq, ord, hash, to_yojson]
include StdLeaf
let pretty () n = text n
+ let pp ppf n = Format.pp_print_string ppf n
let show n = n
let name () = "String"
let printXml f x = BatPrintf.fprintf f "\n\n%s\n\n\n" x
@@ -756,6 +788,7 @@ struct
let show _ = failwith Message.message
let pretty _ _ = failwith Message.message
+ let pp _ _ = failwith Message.message
let printXml _ _ = failwith Message.message
let to_yojson _ = failwith Message.message
diff --git a/src/common/framework/controlSpecC.ml b/src/common/framework/controlSpecC.ml
index eaec77f6c5..d83db16f8d 100644
--- a/src/common/framework/controlSpecC.ml
+++ b/src/common/framework/controlSpecC.ml
@@ -31,6 +31,7 @@ let tag x =
let show x =
let module C = (val !control_spec_c) in
C.show (Obj.obj x)
+let pp ppf x = Format.pp_print_string ppf (show x)
let pretty () x =
let module C = (val !control_spec_c) in
C.pretty () (Obj.obj x)
diff --git a/src/common/framework/node.ml b/src/common/framework/node.ml
index 906f9e1d77..fcd580d059 100644
--- a/src/common/framework/node.ml
+++ b/src/common/framework/node.ml
@@ -40,6 +40,8 @@ include Printable.SimplePretty (
)
(* TODO: deriving to_yojson gets overridden by SimplePretty *)
+let pp_trace ppf x = Format.pp_print_string ppf (show x)
+
(** Show node ID for CFG and results output. *)
let show_id = function
| Statement stmt -> string_of_int stmt.sid
diff --git a/src/common/util/gobFormat.ml b/src/common/util/gobFormat.ml
index 8f26ff0087..a194708b5f 100644
--- a/src/common/util/gobFormat.ml
+++ b/src/common/util/gobFormat.ml
@@ -28,3 +28,7 @@ let asprintf (fmt: ('a, Format.formatter, unit, string) format4): 'a =
Format.asprintf ("%t" ^^ fmt) pp_set_infinite_geometry
let asprint pp x = asprintf "%a" pp x (* eta-expanded to bypass value restriction *)
+
+let pp_print_opt ?(none="?") pp ppf = function
+ | None -> Format.pp_print_string ppf none
+ | Some x -> pp ppf x
diff --git a/src/constraint/constrSys.ml b/src/constraint/constrSys.ml
index 7857d5a543..9e4fbdbd59 100644
--- a/src/constraint/constrSys.ml
+++ b/src/constraint/constrSys.ml
@@ -13,6 +13,7 @@ sig
include Hashtbl.HashedType
include SysVar with type t := t
val pretty_trace: unit -> t -> GoblintCil.Pretty.doc
+ val pp_trace: Format.formatter -> t -> unit
val compare : t -> t -> int
val printXml : 'a BatInnerIO.output -> t -> unit
@@ -37,6 +38,8 @@ struct
| `L a -> GoblintCil.Pretty.dprintf "L:%a" LV.pretty_trace a
| `G a -> GoblintCil.Pretty.dprintf "G:%a" GV.pretty_trace a
+ let pp_trace ppf x = Format.pp_print_string ppf (GobPretty.sprint pretty_trace x)
+
let printXml f = function
| `L a -> LV.printXml f a
| `G a -> GV.printXml f a
diff --git a/src/domain/flagHelper.ml b/src/domain/flagHelper.ml
index c3bcb584b2..fe1eb2d18e 100644
--- a/src/domain/flagHelper.ml
+++ b/src/domain/flagHelper.ml
@@ -31,6 +31,7 @@ struct
| _ -> failwith Msg.msg
let show = unop L.show R.show
+ let pp ppf x = Format.pp_print_string ppf (show x)
let pretty () = unop (L.pretty ()) (R.pretty ())
let printXml f = unop (L.printXml f) (R.printXml f)
let to_yojson = unop L.to_yojson R.to_yojson
diff --git a/src/domain/hoareDomain.ml b/src/domain/hoareDomain.ml
index 1bd56c0d1d..f7edc1a632 100644
--- a/src/domain/hoareDomain.ml
+++ b/src/domain/hoareDomain.ml
@@ -162,6 +162,11 @@ struct
let content = List.fold_left (++) nil separated in
(text "{") ++ content ++ (text "}")
+ let pp ppf x =
+ let pp_sep ppf () = Format.fprintf ppf ", " in
+ Format.fprintf ppf "{%a}"
+ (Format.pp_print_list ~pp_sep E.pp) (elements x)
+
let pretty_diff () ((x:t),(y:t)): Pretty.doc =
Pretty.dprintf "HoarePO: %a not leq %a" pretty x pretty y
let printXml f x =
diff --git a/src/domain/mapDomain.ml b/src/domain/mapDomain.ml
index cf563dab44..0963c05cb1 100644
--- a/src/domain/mapDomain.ml
+++ b/src/domain/mapDomain.ml
@@ -79,6 +79,17 @@ struct
let show map = GobPretty.sprint pretty map
+ let pp ppf map =
+ let first = ref true in
+ Format.fprintf ppf "@[{";
+ M.iter (fun k v ->
+ if !first then (first := false; Format.fprintf ppf "@[@,")
+ else Format.fprintf ppf "@,";
+ Format.fprintf ppf "@[%a ->@ @[%a@]@]" D.pp k R.pp v
+ ) map;
+ if !first then Format.fprintf ppf "}"
+ else Format.fprintf ppf "@]}@]"
+
let printXml f map =
BatPrintf.fprintf f "\n