cocci.inria.fr archive mirror
 help / color / mirror / Atom feed
* [cocci] [PATCH 1/2] engine/postprocess_transinfo.ml: Fix indentation
@ 2022-09-03  9:38 Jan Tojnar
  2022-09-03  9:38 ` [cocci] [PATCH 2/2] Distinguish script-based fresh ids with differing args Jan Tojnar
  0 siblings, 1 reply; 5+ messages in thread
From: Jan Tojnar @ 2022-09-03  9:38 UTC (permalink / raw)
  To: cocci; +Cc: Jan Tojnar

Previously, the file mixed tabs and spaces inconsistently,
making viewing diffs annoying.

Let’s replace tabs with eight spaces,
which appears to be the assumed value.

This Separate commit to make the successive diff cleaner.

Signed-off-by: Jan Tojnar <jtojnar@gmail.com>
---
 engine/postprocess_transinfo.ml | 172 ++++++++++++++++----------------
 1 file changed, 86 insertions(+), 86 deletions(-)

diff --git a/engine/postprocess_transinfo.ml b/engine/postprocess_transinfo.ml
index 5536f09c..2a00b797 100644
--- a/engine/postprocess_transinfo.ml
+++ b/engine/postprocess_transinfo.ml
@@ -51,104 +51,104 @@ let process_tree inherited_env l =
   let (all_fresh,local_freshs,new_triples) =
     List.fold_left
       (function (all_fresh,local_freshs,new_triples) ->
-	function (node,env,pred) ->
-	  let (other,fresh) = get_vars pred in
-	  let env = List.filter (function (x,_) -> List.mem x other) env in
-	  (Common.union_set fresh all_fresh,
-	   fresh::local_freshs,
-	   (node,env@inherited_env,pred)::new_triples))
+        function (node,env,pred) ->
+          let (other,fresh) = get_vars pred in
+          let env = List.filter (function (x,_) -> List.mem x other) env in
+          (Common.union_set fresh all_fresh,
+           fresh::local_freshs,
+           (node,env@inherited_env,pred)::new_triples))
       ([],[],[]) l in
   let local_freshs = List.rev local_freshs in
   let new_triples = List.rev new_triples in
   let fresh_env =
     List.map
       (function
-	  ((r,n) as fresh,Ast.NoVal) ->
-	    Printf.printf "%s: name for %s: " r n; (* not debugging code!!! *)
-	    flush stdout;
-	    (fresh,let v = string2val(read_fresh_id()) in function _ -> v)
-	| ((r,n) as fresh,Ast.StringSeed seed) ->
-	    (fresh,let v = string2val(get_seeded seed) in function _ -> v)
-	| ((r,n) as fresh,Ast.ListSeed seed) ->
-	    (fresh,
-	     function env ->
-	       let strings =
-		 List.map
-		   (function
-		       Ast.SeedString s -> s
-		     | Ast.SeedId id ->
-			 try
-			   (match List.assoc id env with
-			     Lib_engine.NormalMetaVal(Ast_c.MetaIdVal str) ->
-			       str
-			   | _ -> failwith "bad id value")
-			 with
-			   Not_found ->
-			     failwith
-			       ("fresh: no binding for meta "^(Dumper.dump id)))
-		   seed in
-	       string2val(String.concat "" strings))
+          ((r,n) as fresh,Ast.NoVal) ->
+            Printf.printf "%s: name for %s: " r n; (* not debugging code!!! *)
+            flush stdout;
+            (fresh,let v = string2val(read_fresh_id()) in function _ -> v)
+        | ((r,n) as fresh,Ast.StringSeed seed) ->
+            (fresh,let v = string2val(get_seeded seed) in function _ -> v)
+        | ((r,n) as fresh,Ast.ListSeed seed) ->
+            (fresh,
+             function env ->
+               let strings =
+                 List.map
+                   (function
+                       Ast.SeedString s -> s
+                     | Ast.SeedId id ->
+                         try
+                           (match List.assoc id env with
+                             Lib_engine.NormalMetaVal(Ast_c.MetaIdVal str) ->
+                               str
+                           | _ -> failwith "bad id value")
+                         with
+                           Not_found ->
+                             failwith
+                               ("fresh: no binding for meta "^(Dumper.dump id)))
+                   seed in
+               string2val(String.concat "" strings))
         | ((r, n) as fresh, Ast.ScriptSeed(name, lang, params, pos, body)) ->
-	    let res = ref None in
+            let res = ref None in
             let make_fresh_id env =
-	      match !res with
-		Some x -> x
-	      | None ->
-		  let args =
+              match !res with
+                Some x -> x
+              | None ->
+                  let args =
                     List.map
                       (fun (((rule, name) as meta_name), _) ->
-			try match List.assoc meta_name env with
-			| Lib_engine.NormalMetaVal v -> (meta_name, v)
-			| _ ->
+                        try match List.assoc meta_name env with
+                        | Lib_engine.NormalMetaVal v -> (meta_name, v)
+                        | _ ->
                             failwith
                               (Printf.sprintf
-				 "Undesired metavar_binding in line %d"
-				 (snd pos))
-			with
-			| Not_found ->
+                                 "Undesired metavar_binding in line %d"
+                                 (snd pos))
+                        with
+                        | Not_found ->
                             let get_meta_names l =
                               List.map
-				(fun (mn, _) -> Ast.string_of_meta_name mn)
-				l in
+                                (fun (mn, _) -> Ast.string_of_meta_name mn)
+                                l in
                             let string_of_list l =
                               "[" ^ String.concat "; " l ^ "]" in
                             failwith
                               (Printf.sprintf
-				 "%s: script on variable %s cannot be evaluated in line %d. available: %s\nwanted: %s"
-				 r n (snd pos)
-				 (string_of_list (get_meta_names env))
-				 (string_of_list (get_meta_names params)))
-			      )
+                                 "%s: script on variable %s cannot be evaluated in line %d. available: %s\nwanted: %s"
+                                 r n (snd pos)
+                                 (string_of_list (get_meta_names env))
+                                 (string_of_list (get_meta_names params)))
+                              )
                       params in
-		  let args = (fresh, Ast_c.MetaIdVal n)::args in
-		  let fresh_id =
+                  let args = (fresh, Ast_c.MetaIdVal n)::args in
+                  let fresh_id =
                     match lang with
                     | "ocaml" ->
-			Run_ocamlcocci.run_fresh_id name (List.map snd args)
+                        Run_ocamlcocci.run_fresh_id name (List.map snd args)
                     | "python" -> Pycocci.run_fresh_id args pos body
                     | _ ->
-			failwith
-			  "languages other than ocaml or python not supported" in
-		  let r = string2val fresh_id in
-		  res := Some r;
-		  r in
+                        failwith
+                          "languages other than ocaml or python not supported" in
+                  let r = string2val fresh_id in
+                  res := Some r;
+                  r in
             (fresh, make_fresh_id)
       )
       all_fresh in
   let (_,res) =
     List.split
       (List.fold_left
-	 (function freshs_node_env_preds ->
-	   function (fresh,fn) ->
-	     List.map
-	       (function (freshs,((node,env,pred) as cur)) ->
-		 try
-		   let _ = List.assoc fresh freshs in
-		   (freshs,(node,(fresh,fn env)::env,pred))
-		 with Not_found -> (freshs,cur))
-	       freshs_node_env_preds)
-	 (List.combine local_freshs new_triples)
-	 fresh_env) in
+         (function freshs_node_env_preds ->
+           function (fresh,fn) ->
+             List.map
+               (function (freshs,((node,env,pred) as cur)) ->
+                 try
+                   let _ = List.assoc fresh freshs in
+                   (freshs,(node,(fresh,fn env)::env,pred))
+                 with Not_found -> (freshs,cur))
+               freshs_node_env_preds)
+         (List.combine local_freshs new_triples)
+         fresh_env) in
   (List.rev res, fresh_env)
 
 (* ----------------------------------------------------------------------- *)
@@ -161,16 +161,16 @@ let collect_used_after used_after envs l inherited_env =
   List.map2
     (function env -> function l ->
       let inherited_env =
-	match l with
-	  [] -> inherited_env
-	| (_,fse,_)::_ ->
-	    (* l represents the result from a single tree. fse is a complete
-	       environment in that tree.  for a fresh seed, the environments
-	       for all leaves contain the same information *)
-	    fse@inherited_env  in
+        match l with
+          [] -> inherited_env
+        | (_,fse,_)::_ ->
+            (* l represents the result from a single tree. fse is a complete
+               environment in that tree.  for a fresh seed, the environments
+               for all leaves contain the same information *)
+            fse@inherited_env  in
       List.map
-	(function (v,vl) -> (v,vl inherited_env))
-	(List.filter (function (v,vl) -> List.mem v used_after) env))
+        (function (v,vl) -> (v,vl inherited_env))
+        (List.filter (function (v,vl) -> List.mem v used_after) env))
     envs l
 
 (* ----------------------------------------------------------------------- *)
@@ -183,24 +183,24 @@ let fold_left_with_index f acc =
   let rec fold_lwi_aux acc = function
     | [] -> acc
     | x::xs ->
-	let n = !index in
-	index := !index + 1;
-	fold_lwi_aux (f acc x n) xs
+        let n = !index in
+        index := !index + 1;
+        fold_lwi_aux (f acc x n) xs
   in fold_lwi_aux acc
 
 let numberify trees =
   let trees =
     fold_left_with_index
       (function acc -> function xs -> function n ->
-	(List.map (function x -> (n,x)) xs) @ acc)
+        (List.map (function x -> (n,x)) xs) @ acc)
       [] trees in
   List.fold_left
     (function res ->
       function (n,x) ->
-	let (same,diff) = List.partition (function (ns,xs) -> x = xs) res in
-	match same with
-	  [(ns,xs)] -> (n::ns,xs)::diff
-	| _ -> ([n],x)::res)
+        let (same,diff) = List.partition (function (ns,xs) -> x = xs) res in
+        match same with
+          [(ns,xs)] -> (n::ns,xs)::diff
+        | _ -> ([n],x)::res)
     [] trees
 
 (* ----------------------------------------------------------------------- *)
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [cocci] [PATCH 2/2] Distinguish script-based fresh ids with differing args
  2022-09-03  9:38 [cocci] [PATCH 1/2] engine/postprocess_transinfo.ml: Fix indentation Jan Tojnar
@ 2022-09-03  9:38 ` Jan Tojnar
  2022-10-22 12:44   ` Jan Tojnar
  0 siblings, 1 reply; 5+ messages in thread
From: Jan Tojnar @ 2022-09-03  9:38 UTC (permalink / raw)
  To: cocci; +Cc: Jan Tojnar

https://gitlab.inria.fr/coccinelle/coccinelle/-/commit/f4db03ee748c13d7661e5048c355863466def08b
started memoizing the fresh identifiers generated by scripts to keep them
consistent across different rules. But it did not account for the script
producing a different result depending on the values of inherited
metavariables passed to it as explicit arguments.

Let’s memoize the script results in a hash map,
one fresh name per each different argument list.

Fixes: https://github.com/coccinelle/coccinelle/issues/283

Signed-off-by: Jan Tojnar <jtojnar@gmail.com>
---
 engine/postprocess_transinfo.ml | 67 ++++++++++++++++++---------------
 tests/id4.c                     |  5 +++
 tests/id4.cocci                 | 23 +++++++++++
 tests/id4.res                   |  5 +++
 4 files changed, 70 insertions(+), 30 deletions(-)
 create mode 100644 tests/id4.c
 create mode 100644 tests/id4.cocci
 create mode 100644 tests/id4.res

diff --git a/engine/postprocess_transinfo.ml b/engine/postprocess_transinfo.ml
index 2a00b797..e226fb13 100644
--- a/engine/postprocess_transinfo.ml
+++ b/engine/postprocess_transinfo.ml
@@ -15,6 +15,14 @@ how we reached a particular match *)
 
 module Ast = Ast_cocci
 
+module ParamsType =
+  struct
+    type t = Ast_c.metavars_binding
+    let compare = Stdlib.compare
+  end
+
+module ParamsMap = Map.Make(ParamsType)
+
 let extra_counter = ref 0
 
 let reset_fresh_counter () = extra_counter := 0
@@ -89,38 +97,37 @@ let process_tree inherited_env l =
                    seed in
                string2val(String.concat "" strings))
         | ((r, n) as fresh, Ast.ScriptSeed(name, lang, params, pos, body)) ->
-            let res = ref None in
+            let res = ref ParamsMap.empty in
             let make_fresh_id env =
-              match !res with
+              let args =
+                List.map
+                  (fun (((rule, name) as meta_name), _) ->
+                    try match List.assoc meta_name env with
+                    | Lib_engine.NormalMetaVal v -> (meta_name, v)
+                    | _ ->
+                        failwith
+                          (Printf.sprintf
+                             "Undesired metavar_binding in line %d"
+                             (snd pos))
+                    with
+                    | Not_found ->
+                        let get_meta_names l =
+                          List.map
+                            (fun (mn, _) -> Ast.string_of_meta_name mn)
+                            l in
+                        let string_of_list l =
+                          "[" ^ String.concat "; " l ^ "]" in
+                        failwith
+                          (Printf.sprintf
+                             "%s: script on variable %s cannot be evaluated in line %d. available: %s\nwanted: %s"
+                             r n (snd pos)
+                             (string_of_list (get_meta_names env))
+                             (string_of_list (get_meta_names params)))
+                          )
+                  params in
+              match ParamsMap.find_opt args !res with
                 Some x -> x
               | None ->
-                  let args =
-                    List.map
-                      (fun (((rule, name) as meta_name), _) ->
-                        try match List.assoc meta_name env with
-                        | Lib_engine.NormalMetaVal v -> (meta_name, v)
-                        | _ ->
-                            failwith
-                              (Printf.sprintf
-                                 "Undesired metavar_binding in line %d"
-                                 (snd pos))
-                        with
-                        | Not_found ->
-                            let get_meta_names l =
-                              List.map
-                                (fun (mn, _) -> Ast.string_of_meta_name mn)
-                                l in
-                            let string_of_list l =
-                              "[" ^ String.concat "; " l ^ "]" in
-                            failwith
-                              (Printf.sprintf
-                                 "%s: script on variable %s cannot be evaluated in line %d. available: %s\nwanted: %s"
-                                 r n (snd pos)
-                                 (string_of_list (get_meta_names env))
-                                 (string_of_list (get_meta_names params)))
-                              )
-                      params in
-                  let args = (fresh, Ast_c.MetaIdVal n)::args in
                   let fresh_id =
                     match lang with
                     | "ocaml" ->
@@ -130,7 +137,7 @@ let process_tree inherited_env l =
                         failwith
                           "languages other than ocaml or python not supported" in
                   let r = string2val fresh_id in
-                  res := Some r;
+                  res := ParamsMap.add args r !res;
                   r in
             (fresh, make_fresh_id)
       )
diff --git a/tests/id4.c b/tests/id4.c
new file mode 100644
index 00000000..bb5f99e3
--- /dev/null
+++ b/tests/id4.c
@@ -0,0 +1,5 @@
+void foo() {
+    Foo *widget;
+    widget->window;
+    widget->parent;
+}
diff --git a/tests/id4.cocci b/tests/id4.cocci
new file mode 100644
index 00000000..2619f09e
--- /dev/null
+++ b/tests/id4.cocci
@@ -0,0 +1,23 @@
+@initialize:python@
+@@
+
+def make_prefix_from_type(type_name):
+    # Get just the type name without surrounding whitespace or pointer asterisk.
+    return type_name.strip().strip("*").strip()
+
+def make_getter_name(prefix, member_name):
+    return prefix + "_get_" + member_name
+
+@r1@
+// Getter on declared variables
+type type_name;
+identifier object_var;
+identifier member_name;
+fresh identifier getter_name = script:python(type_name, member_name) { make_getter_name(make_prefix_from_type(type_name), member_name) };
+@@
+
+type_name object_var;
+<...
+-object_var->member_name
++getter_name(object_var)
+...>
diff --git a/tests/id4.res b/tests/id4.res
new file mode 100644
index 00000000..f529a4d6
--- /dev/null
+++ b/tests/id4.res
@@ -0,0 +1,5 @@
+void foo() {
+    Foo *widget;
+    Foo_get_window(widget);
+    Foo_get_parent(widget);
+}
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [cocci] [PATCH 2/2] Distinguish script-based fresh ids with differing args
  2022-09-03  9:38 ` [cocci] [PATCH 2/2] Distinguish script-based fresh ids with differing args Jan Tojnar
@ 2022-10-22 12:44   ` Jan Tojnar
  2022-10-22 12:46     ` Julia Lawall
  0 siblings, 1 reply; 5+ messages in thread
From: Jan Tojnar @ 2022-10-22 12:44 UTC (permalink / raw)
  To: Julia Lawall; +Cc: cocci

Hi Julia,

Could you please review the above patch, when you have time? It fixes
the regression in `fresh identifiers` in conjunction with scripts from
master.

Cheers,

Jan

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [cocci] [PATCH 2/2] Distinguish script-based fresh ids with differing args
  2022-10-22 12:44   ` Jan Tojnar
@ 2022-10-22 12:46     ` Julia Lawall
  2022-10-22 12:56       ` Jan Tojnar
  0 siblings, 1 reply; 5+ messages in thread
From: Julia Lawall @ 2022-10-22 12:46 UTC (permalink / raw)
  To: Jan Tojnar; +Cc: cocci



On Sat, 22 Oct 2022, Jan Tojnar wrote:

> Hi Julia,
>
> Could you please review the above patch, when you have time? It fixes
> the regression in `fresh identifiers` in conjunction with scripts from
> master.

Yes, I will take care of it.  Thanks for the contribution, and sorry for
the delay.

julia

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [cocci] [PATCH 2/2] Distinguish script-based fresh ids with differing args
  2022-10-22 12:46     ` Julia Lawall
@ 2022-10-22 12:56       ` Jan Tojnar
  0 siblings, 0 replies; 5+ messages in thread
From: Jan Tojnar @ 2022-10-22 12:56 UTC (permalink / raw)
  To: Julia Lawall; +Cc: cocci

On Sat, 22 Oct 2022 at 14:46, Julia Lawall <julia.lawall@inria.fr> wrote:
>
> Yes, I will take care of it.  Thanks for the contribution, and sorry for
> the delay.

No worries, I am applying the patch locally for now. Just wanted to
mention it so that the regression does not sneak into the next
Coccinelle release.

Jan

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-10-22 12:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-03  9:38 [cocci] [PATCH 1/2] engine/postprocess_transinfo.ml: Fix indentation Jan Tojnar
2022-09-03  9:38 ` [cocci] [PATCH 2/2] Distinguish script-based fresh ids with differing args Jan Tojnar
2022-10-22 12:44   ` Jan Tojnar
2022-10-22 12:46     ` Julia Lawall
2022-10-22 12:56       ` Jan Tojnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).