[Cocci] [PATCH v2] coccinelle: api: add kvmalloc script
Suggest kvmalloc instead of opencoded kmalloc && vmalloc condition. Signed-off-by: Denis Efremov --- Changes in v2: - binary operator cmp added - NULL comparisions simplified - "T x" case added to !patch mode scripts/coccinelle/api/kvmalloc.cocci | 142 ++ 1 file changed, 142 insertions(+) create mode 100644 scripts/coccinelle/api/kvmalloc.cocci diff --git a/scripts/coccinelle/api/kvmalloc.cocci b/scripts/coccinelle/api/kvmalloc.cocci new file mode 100644 index ..20b22e3d0f74 --- /dev/null +++ b/scripts/coccinelle/api/kvmalloc.cocci @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// +/// Find if/else condition with kmalloc/vmalloc calls. +/// Suggest to use kvmalloc instead. +/// +// Confidence: High +// Copyright: (C) 2020 Denis Efremov ISPRAS +// Options: --no-includes --include-headers +// + +virtual patch +virtual report +virtual org +virtual context + +@opportunity depends on !patch@ +expression E, E1, size; +binary operator cmp = {<=, <, ==, >, >=}; +identifier x; +type T; +position p; +@@ + +( +* if (size cmp E1 || ...)@p { +... +*E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| +* kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(..., size, ...) +... + } else { +... +*E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) +... + } +| +* E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| +* kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(..., size, ...) + ... when != E = E1 + when != size = E1 + when any +* if (E == NULL)@p { +... +* E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) +... + } +| +* T x = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| +* kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(..., size, ...); + ... when != x = E1 + when != size = E1 + when any +* if (x == NULL)@p { +... +* x = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) +... + } +) + +@depends on patch@ +expression E, E1, flags, size, node; +binary operator cmp = {<=, <, ==, >, >=}; +identifier x; +type T; +@@ + +( +- if (size cmp E1) +-E = kmalloc(size, flags); +- else +-E = vmalloc(size); ++ E = kvmalloc(size, flags); +| +- E = kmalloc(size, flags | __GFP_NOWARN); +- if (E == NULL) +- E = vmalloc(size); ++ E = kvmalloc(size, flags); +| +- T x = kmalloc(size, flags | __GFP_NOWARN); +- if (x == NULL) +- x = vmalloc(size); ++ T x = kvmalloc(size, flags); +| +- if (size cmp E1) +-E = kzalloc(size, flags); +- else +-E = vzalloc(size); ++ E = kvzalloc(size, flags); +| +- E = kzalloc(size, flags | __GFP_NOWARN); +- if (E == NULL) +- E = vzalloc(size); ++ E = kvzalloc(size, flags); +| +- T x = kzalloc(size, flags | __GFP_NOWARN); +- if (x == NULL) +- x = vzalloc(size); ++ T x = kvzalloc(size, flags); +| +- if (size cmp E1) +-E = kmalloc_node(size, flags, node); +- else +-E = vmalloc_node(size, node); ++ E = kvmalloc_node(size, flags, node); +| +- E = kmalloc_node(size, flags | __GFP_NOWARN, node); +- if (E == NULL) +- E = vmalloc_node(size, node); ++ E = kvmalloc_node(size, flags, node); +| +- T x = kmalloc_node(size, flags | __GFP_NOWARN, node); +- if (x == NULL) +- x = vmalloc_node(size, node); ++ T x = kvmalloc_node(size, flags, node); +| +- if (size cmp E1) +-E = kvzalloc_node(size, flags, node); +- else +-E = vzalloc_node(size, node); ++ E = kvzalloc_node(size, flags, node); +| +- E = kvzalloc_node(size, flags | __GFP_NOWARN, node); +- if (E == NULL) +- E = vzalloc_node(size, node); ++ E = kvzalloc_node(size, flags, node); +| +- T x = kvzalloc_node(size, flags | __GFP_NOWARN, node); +- if (x == NULL) +- x = vzalloc_node(size, node); ++ T x = kvzalloc_node(size, flags, node); +) + +@script: python depends on report@ +p << opportunity.p; +@@ + +coccilib.report.print_report(p[0], "WARNING: opportunity for kvmalloc") + +@script: python depends on org@ +p << opportunity.p; +@@ + +coccilib.org.print_todo(p[0], "WARNING: opportunity for kvmalloc") -- 2.26.2 ___ Cocci mailing list Cocci@systeme.lip6.fr https://systeme.lip6.fr/mailman/listinfo/cocci
[Cocci] [PATCH v7] coccinelle: api: add kfree_mismatch script
Check that alloc and free types of functions match each other. Signed-off-by: Denis Efremov --- Changes in v2: - Lines are limited to 80 characters where possible - Confidence changed from High to Medium because of fs/btrfs/send.c:1119 false-positive - __vmalloc_area_node() explicitly excluded from analysis instead of !(file in "mm/vmalloc.c") condition Changes in v3: - prints style in org && report modes changed for python2 Changes in v4: - missing msg argument to print_todo fixed Changes in v5: - fix position p in kfree rule - move @kok and @v positions in choice rule after the arguments - remove kvmalloc suggestions Changes in v6: - more asterisks added in context mode - second @kok added to the choice rule Changes in v7: - file renamed to kfree_mismatch.cocci - python function relevant() removed - additional rule for filtering free positions added - btrfs false-positive fixed - confidence level changed to high - kvfree_switch rule added - names for position variables changed to @a (alloc) and @f (free) scripts/coccinelle/api/kfree_mismatch.cocci | 229 1 file changed, 229 insertions(+) create mode 100644 scripts/coccinelle/api/kfree_mismatch.cocci diff --git a/scripts/coccinelle/api/kfree_mismatch.cocci b/scripts/coccinelle/api/kfree_mismatch.cocci new file mode 100644 index ..9e9ef9fd7a25 --- /dev/null +++ b/scripts/coccinelle/api/kfree_mismatch.cocci @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// +/// Check that kvmalloc'ed memory is freed by kfree functions, +/// vmalloc'ed by vfree functions and kvmalloc'ed by kvfree +/// functions. +/// +// Confidence: High +// Copyright: (C) 2020 Denis Efremov ISPRAS +// Options: --no-includes --include-headers +// + +virtual patch +virtual report +virtual org +virtual context + +@alloc@ +expression E, E1; +position kok, vok; +@@ + +( + if (...) { +... +E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\| + kmalloc_node\|kzalloc_node\|kmalloc_array\| + kmalloc_array_node\|kcalloc_node\)(...)@kok +... + } else { +... +E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\| + vzalloc_node\|vmalloc_exec\|vmalloc_32\| + vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\| + __vmalloc_node\)(...)@vok +... + } +| + E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\|kzalloc_node\| +kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(...)@kok + ... when != E = E1 + when any + if (E == NULL) { +... +E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\| + vzalloc_node\|vmalloc_exec\|vmalloc_32\| + vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\| + __vmalloc_node\)(...)@vok +... + } +) + +@free@ +expression E; +position fok; +@@ + + E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\| +kvmalloc_array\)(...) + ... + kvfree(E)@fok + +@vfree depends on !patch@ +expression E; +position a != alloc.kok; +position f != free.fok; +@@ + +* E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\| +* kzalloc_node\|kmalloc_array\|kmalloc_array_node\| +* kcalloc_node\)(...)@a + ... when != if (...) { ... E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|__vmalloc_node\)(...); ... } + when != is_vmalloc_addr(E) + when any +* \(vfree\|vfree_atomic\|kvfree\)(E)@f + +@depends on patch exists@ +expression E; +position a != alloc.kok; +position f != free.fok; +@@ + + E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\| +kzalloc_node\|kmalloc_array\|kmalloc_array_node\| +kcalloc_node\)(...)@a + ... when != if (...) { ... E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|__vmalloc_node\)(...); ... } + when != is_vmalloc_addr(E) + when any +- \(vfree\|vfree_atomic\|kvfree\)(E)@f ++ kfree(E) + +@kfree depends on !patch@ +expression E; +position a != alloc.vok; +position f != free.fok; +@@ + +* E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\| +* vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\| +* __vmalloc_node_range\|__vmalloc_node\)(...)@a + ... when != is_vmalloc_addr(E) + when any +* \(kfree\|kzfree\|kvfree\)(E)@f + +@depends on patch exists@ +expression E; +position a != alloc.vok; +position f != free.fok; +@@ + + E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\| +vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\| +__vmalloc_node_range\|__vmalloc_node\)(...)@a + ... when != is_vmalloc_addr(E) + when any +- \(kfree\|kvfree\)(E)@f ++ vfree(E) + +@kvfree depends on !patch@ +expression E; +position a, f; +@@ + +* E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\| +* kvmalloc_array\)(...)@a + ... when != is_vmalloc_addr(E) +
Re: [Cocci] [PATCH] coccinelle: api: add kvmalloc script
On Mon, 3 Aug 2020, Markus Elfring wrote: > … > > +++ b/scripts/coccinelle/api/kvmalloc.cocci > … > > +@opportunity depends on !patch@ > > +expression E, E1, size; > > +position p; > > +@@ > > + > > +( > … > > +| > > +* E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| > > +* kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(..., size, ...) > > + ... when != E = E1 > > + when != size = E1 > > + when any > > +* if (\(!E\|E == NULL\))@p { Actually, you shouldn't need both E == NULL and !E. E == NULL should be sufficient. julia > … > > I suggest to extend the SmPL code exclusion specification so that > pointer dereferences will be filtered out before the shown null pointer > detection. > > > > +@depends on patch@ > > +expression E, E1, flags, size, node; > > +identifier x; > > +type T; > > +@@ > > + > > +( > > +- if (\(size <= E1\|size < E1\|size == E1\|size > E1\)) > > This condition check is repeated a few times. > Thus I imagine that the usage of another metavariable with a SmPL constraint > can eventually be helpful. > > +binary operator bo = {<=, <, ==, >}; > … > +-if (size bo E1) > > > > > +-E = kmalloc(size, flags); > > +- else > > +-E = vmalloc(size); > > Will it be interesting to support also the use of conditional operators > by another part of a SmPL disjunction? > > -E = (…) ? kmalloc(size, flags) : vmalloc(size); > > > > ++ E = kvmalloc(size, flags); > > +| > > +- E = kmalloc(size, flags | __GFP_NOWARN); > > +- if (\(!E\|E == NULL\)) > > +- E = vmalloc(size); > > ++ E = kvmalloc(size, flags); > > This source code replacement line is repeated. Thus I imagine > that it would be nice if such SmPL code duplication could be avoided > by the application of another SmPL disjunction. > Unfortunately, the software “Coccinelle 1.0.8-00146-g04f36d53” presents > the error message “15: no available token to attach to” then. > Would you like to adjust anything in this area? > > Regards, > Markus >___ Cocci mailing list Cocci@systeme.lip6.fr https://systeme.lip6.fr/mailman/listinfo/cocci
Re: [Cocci] [PATCH v6] coccinelle: api: add kvfree script
On Mon, 3 Aug 2020, Denis Efremov wrote: > > > On 8/2/20 11:24 PM, Julia Lawall wrote: > >> +@initialize:python@ > >> +@@ > >> +# low-level memory api > >> +filter = frozenset(['__vmalloc_area_node']) > >> + > >> +def relevant(p): > >> +return not (filter & {el.current_element for el in p}) > > > > Is this used? > > I'll remove it in v8. Or do you want me to add iterate_dir_item() in the list? What is that? > > > > > Otherwise, I think it would be good to not warn about a use of kvfree > > if that use is reachable from a kvmalloc. There seems to be such a false > > positive in fs/btrfs/send.c, on line 1118. > > I don't know how to handle this case without position filter. > It's too complex. In iterate_dir_item() there is: > buf = kmalloc(buf_len, GFP_KERNEL); > while(...) { > if (...) { > if (is_vmalloc_addr(buf)) { > vfree(buf); > ... > } else { > char *tmp = krealloc(buf, ...); > > if (!tmp) > kfree(buf); > ... > } > if (!buf) { > buf = kvmalloc(buf_len, GFP_KERNEL); > ... > } > } > } > kvfree(buf); > > Adding "when != kvfree(E)" is not enough: > * E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\| > * kvmalloc_array\)(...)@k > ... when != is_vmalloc_addr(E) > + when != kvfree(E) > when any > * \(kfree\|kzfree\|vfree\|vfree_atomic\)(E)@p Why not just @ok exists@ position p; expression E; @@ E = kvalloc(...) ... kvfree@p(...) Probably that is what you mean by a position filter, but why not add a position filter? julia > > > > It also seems that when there are both a kmalloc and a vmalloc, there is > > no warning if kfree or vfree is used. Is that intentional? > > > > No, I will try to address it in v8. > > Regards, > Denis > ___ Cocci mailing list Cocci@systeme.lip6.fr https://systeme.lip6.fr/mailman/listinfo/cocci
Re: [Cocci] [PATCH v6] coccinelle: api: add kvfree script
On Mon, 3 Aug 2020, Denis Efremov wrote: > Is there a difference from cocci point of view between: > > ... when != !is_vmalloc_addr(E) This will only reject cases where the ! is present. Coccinelle doesn't apply isomorphisms to the C source code, so it doesn't detect that eg if (A) B else C could be rewritten as if (!A) C ese B So when != !A would only match when the code is in the second form. > > and > > ... when != is_vmalloc_addr(E) > > Should the latter one be used in most cases? This matches both a call to is_vmalloc_addr and a negated call, so it is more general. julia ___ Cocci mailing list Cocci@systeme.lip6.fr https://systeme.lip6.fr/mailman/listinfo/cocci
Re: [Cocci] [PATCH v6] coccinelle: api: add kvfree script
Is there a difference from cocci point of view between: ... when != !is_vmalloc_addr(E) and ... when != is_vmalloc_addr(E) Should the latter one be used in most cases? Thanks, Denis ___ Cocci mailing list Cocci@systeme.lip6.fr https://systeme.lip6.fr/mailman/listinfo/cocci
Re: [Cocci] [PATCH v6] coccinelle: api: add kvfree script
On 8/2/20 11:24 PM, Julia Lawall wrote: >> +@initialize:python@ >> +@@ >> +# low-level memory api >> +filter = frozenset(['__vmalloc_area_node']) >> + >> +def relevant(p): >> +return not (filter & {el.current_element for el in p}) > > Is this used? I'll remove it in v8. Or do you want me to add iterate_dir_item() in the list? > > Otherwise, I think it would be good to not warn about a use of kvfree > if that use is reachable from a kvmalloc. There seems to be such a false > positive in fs/btrfs/send.c, on line 1118. I don't know how to handle this case without position filter. It's too complex. In iterate_dir_item() there is: buf = kmalloc(buf_len, GFP_KERNEL); while(...) { if (...) { if (is_vmalloc_addr(buf)) { vfree(buf); ... } else { char *tmp = krealloc(buf, ...); if (!tmp) kfree(buf); ... } if (!buf) { buf = kvmalloc(buf_len, GFP_KERNEL); ... } } } kvfree(buf); Adding "when != kvfree(E)" is not enough: * E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\| * kvmalloc_array\)(...)@k ... when != is_vmalloc_addr(E) + when != kvfree(E) when any * \(kfree\|kzfree\|vfree\|vfree_atomic\)(E)@p > > It also seems that when there are both a kmalloc and a vmalloc, there is > no warning if kfree or vfree is used. Is that intentional? > No, I will try to address it in v8. Regards, Denis ___ Cocci mailing list Cocci@systeme.lip6.fr https://systeme.lip6.fr/mailman/listinfo/cocci
[Cocci] [PATCH] coccinelle: api: add kvmalloc script
Suggest kvmalloc instead of opencoded kmalloc && vmalloc condition. Signed-off-by: Denis Efremov --- If coccinelle fails with "Segmentation fault" during analysis, then one needs to increase stack limit, e.g. ulimit -s 32767. Current, I've sent only one patch for this rule and will send the rest after the merge window. https://lkml.org/lkml/2020/7/31/986 scripts/coccinelle/api/kvmalloc.cocci | 127 ++ 1 file changed, 127 insertions(+) create mode 100644 scripts/coccinelle/api/kvmalloc.cocci diff --git a/scripts/coccinelle/api/kvmalloc.cocci b/scripts/coccinelle/api/kvmalloc.cocci new file mode 100644 index ..76d6aeab7c09 --- /dev/null +++ b/scripts/coccinelle/api/kvmalloc.cocci @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// +/// Find conditions in code for kmalloc/vmalloc calls. +/// Suggest to use kvmalloc instead. +/// +// Confidence: High +// Copyright: (C) 2020 Denis Efremov ISPRAS +// Options: --no-includes --include-headers +// + +virtual patch +virtual report +virtual org +virtual context + +@opportunity depends on !patch@ +expression E, E1, size; +position p; +@@ + +( +* if (\(size <= E1\|size < E1\|size == E1\|size > E1\) || ...)@p { +... +*E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| +* kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(..., size, ...) +... + } else { +... +*E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) +... + } +| +* E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| +* kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(..., size, ...) + ... when != E = E1 + when != size = E1 + when any +* if (\(!E\|E == NULL\))@p { +... +* E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) +... + } +) + +@depends on patch@ +expression E, E1, flags, size, node; +identifier x; +type T; +@@ + +( +- if (\(size <= E1\|size < E1\|size == E1\|size > E1\)) +-E = kmalloc(size, flags); +- else +-E = vmalloc(size); ++ E = kvmalloc(size, flags); +| +- E = kmalloc(size, flags | __GFP_NOWARN); +- if (\(!E\|E == NULL\)) +- E = vmalloc(size); ++ E = kvmalloc(size, flags); +| +- T x = kmalloc(size, flags | __GFP_NOWARN); +- if (\(!x\|x == NULL\)) +- x = vmalloc(size); ++ T x = kvmalloc(size, flags); +| +- if (\(size <= E1\|size < E1\|size == E1\|size > E1\)) +-E = kzalloc(size, flags); +- else +-E = vzalloc(size); ++ E = kvzalloc(size, flags); +| +- E = kzalloc(size, flags | __GFP_NOWARN); +- if (\(!E\|E == NULL\)) +- E = vzalloc(size); ++ E = kvzalloc(size, flags); +| +- T x = kzalloc(size, flags | __GFP_NOWARN); +- if (\(!x\|x == NULL\)) +- x = vzalloc(size); ++ T x = kvzalloc(size, flags); +| +- if (\(size <= E1\|size < E1\|size == E1\|size > E1\)) +-E = kmalloc_node(size, flags, node); +- else +-E = vmalloc_node(size, node); ++ E = kvmalloc_node(size, flags, node); +| +- E = kmalloc_node(size, flags | __GFP_NOWARN, node); +- if (\(!E\|E == NULL\)) +- E = vmalloc_node(size, node); ++ E = kvmalloc_node(size, flags, node); +| +- T x = kmalloc_node(size, flags | __GFP_NOWARN, node); +- if (\(!x\|x == NULL\)) +- x = vmalloc_node(size, node); ++ T x = kvmalloc_node(size, flags, node); +| +- if (\(size <= E1\|size < E1\|size == E1\|size > E1\)) +-E = kvzalloc_node(size, flags, node); +- else +-E = vzalloc_node(size, node); ++ E = kvzalloc_node(size, flags, node); +| +- E = kvzalloc_node(size, flags | __GFP_NOWARN, node); +- if (\(!E\|E == NULL\)) +- E = vzalloc_node(size, node); ++ E = kvzalloc_node(size, flags, node); +| +- T x = kvzalloc_node(size, flags | __GFP_NOWARN, node); +- if (\(!x\|x == NULL\)) +- x = vzalloc_node(size, node); ++ T x = kvzalloc_node(size, flags, node); +) + +@script: python depends on report@ +p << opportunity.p; +@@ + +coccilib.report.print_report(p[0], "WARNING: opportunity for kvmalloc") + +@script: python depends on org@ +p << opportunity.p; +@@ + +coccilib.org.print_todo(p[0], "WARNING: opportunity for kvmalloc") -- 2.26.2 ___ Cocci mailing list Cocci@systeme.lip6.fr https://systeme.lip6.fr/mailman/listinfo/cocci
Re: [Cocci] [00/43] cocci: Add support for meta attributes to SmPL
On Mon, 2020-08-03 at 07:37 +0200, Markus Elfring wrote: > > > Do you care if a SmPL name variable would accidentally not be > > > used > > > (like in the script “ > > > https://github.com/coccinelle/coccinelle/blob/04f36d537b9f6c0c127d05184cccd21f1a46b952/tests/metaattr.cocci#L2” > > > )? > > > > It actually is used, to help parsing the .c file. This information > > will > > be added to the documentation shortly. > > I would expect that the following SmPL script variant will generate > also a patch. > (Why would extra “help” be needed for parsing source files?) > > @replacement@ > attribute a; > identifier b; > @@ > -int > +char > b a = 1; > > > By the way: > I have noticed another detail which I find questionable at the > moment. > > elfring@Sonne:~/Projekte/Coccinelle/20160205> spatch --parse-cocci > tests/metaattr-2.cocci > … > ( > -int > >>> char > b a = 1; > -signed > >>> char > -int b a = 1; > ) > … > Probably a pretty printing mistake. I'll fix this. Thanks, Jaskaran. > I would interpret the display for the second part of such a SmPL > disjunction > in the way that a variable definition will be deleted (instead of > taking only > the key word “signed” also into account according to the isomorphism > “add_signed”). > > Regards, > Markus ___ Cocci mailing list Cocci@systeme.lip6.fr https://systeme.lip6.fr/mailman/listinfo/cocci