From: Jan Tojnar <jtojnar@gmail.com>
To: cocci@inria.fr
Cc: Jan Tojnar <jtojnar@gmail.com>
Subject: [cocci] [PATCH 2/2] Distinguish script-based fresh ids with differing args
Date: Sat, 3 Sep 2022 11:38:43 +0200 [thread overview]
Message-ID: <20220903093843.2579539-2-jtojnar@gmail.com> (raw)
In-Reply-To: <20220903093843.2579539-1-jtojnar@gmail.com>
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
next prev parent reply other threads:[~2022-09-03 9:39 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-03 9:38 [cocci] [PATCH 1/2] engine/postprocess_transinfo.ml: Fix indentation Jan Tojnar
2022-09-03 9:38 ` Jan Tojnar [this message]
2022-10-22 12:44 ` [cocci] [PATCH 2/2] Distinguish script-based fresh ids with differing args Jan Tojnar
2022-10-22 12:46 ` Julia Lawall
2022-10-22 12:56 ` Jan Tojnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220903093843.2579539-2-jtojnar@gmail.com \
--to=jtojnar@gmail.com \
--cc=cocci@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.