On Sun, 7 Jun 2020, Denis Efremov wrote:

> I've got a couple of questions about python interface.
> Let us suppose that I want to suppress a couple of matches because they are 
> false-positives.
> However, I still want to check they exists in finalize block and print a 
> warning otherwise.
> This is some kind of self-check for a rule.
>
> For example, there is "test.c" file with:
> extern int function1(void);
> extern int function2(void);
>
> int test(void)
> {
>         return function1();
> }
>
> And the rule test.cocci with:
>
> virtual context
> virtual org
> virtual patch
> virtual report
>
> @initialize:python@
> @@
> matches = [] # global list of all positions to check in finalize
> blacklist = frozenset(['test'])
>
> # Always prints []. Is it normal?
> #print(cocci.files())

At this point yes.  It will give some information when you are in a rule
that is applied to files.

>
> def relevant(p): # suppress functions from blacklist
>       matches.extend(p) # It doesn't work in position script, so I do it here
>       return False if blacklist & { el.current_element for el in p } else 
> True # intersection
>
> @r depends on !patch@
> // It doesn't work. Is it normal?
> //position p: script:python() { matches.extend(p); relevant(p) };

"Doesn't work" means you get a parse error?  The parser of the code inside
the {} is pretty fragile.  Perhaps this could be improved somewhat, but it
is limited by the fact that Coccinelle doesn't know how to parse python
properly.

> position p: script:python() { relevant(p) };
> @@
>
> * function1@p();
>
> @rp depends on patch@
> position p: script:python() { relevant(p) };
> @@
>
> - function1@p();
> + function2();
>
> // Self-check for the rule
> @finalize:python depends on !patch@
> @@
>
> # Always prints []. Is it normal?
> #print(cocci.files())

Again, a finalize is not applide to any files.

> if 'test.c' in cocci.files(): # I know that we should match test definition 
> in test.c
>       not_matched = blacklist - { el.current_element for el in matches }; # 
> set difference
>       if not_matched:
>               print('SELF-CHECK: patterns no longer match definitions for: ' 
> + ','.join(not_matched))
>
> I want to implement this kind of self-check for memdup_user function. I need 
> check that the patterns
> match the function definition, but suppress these diagnostics. And print a 
> warning about changed
> implementation if there is no matches for the patterns in mm/util.c

This seems entirely reasonable.  You can collect the places that are
matched in a variable declared in the initialize, and then look at that
variable in the finalize.

If you tried this and it didn't work, it could be because of parallelism.
When you use the -j option, each child process has its own address
space, and by default they are not combined for the finalize, which is not
run in parallel.  You can see coccinelle/tests/merge_vars_python.cocci.
That doesn't look like a great example though...  Basically, l1 <<
merge.v1 will cause l1 to be a list of the v1 values for the different
cores.  So if you have a list of matched files, then merge will give you a
list of lists of matched files.

julia



> Thanks,
> Denis
> _______________________________________________
> Cocci mailing list
> [email protected]
> https://systeme.lip6.fr/mailman/listinfo/cocci
>
_______________________________________________
Cocci mailing list
[email protected]
https://systeme.lip6.fr/mailman/listinfo/cocci

Reply via email to