2

So, the problem I stumble upon is that code inside if can be pretty complex, it can be stuff like if (NOT(ret = foo())) and also if (foo() == NULL), and other variations are possible.

To me the obvious answer is the rule line if (...foo()...), but Coccinelle says it fails to parse this.

I tried everything I managed to find or to guess, so far to no avail.


As a demo example, here's a test.c

#include <stddef.h>
#include <stdbool.h>

#define NOT(expr) (!(expr))

void remove_this_call_if_foo_is_called() {}
const char* foo() { return "hello"; }
const char* bar() { return "hello"; }

int main() {
    const char* ret;
    if (NOT(ret = foo())) {
        remove_this_call_if_foo_is_called();
    }

    if (foo() == NULL) {
        remove_this_call_if_foo_is_called();
    }

    if (foo()) {
        remove_this_call_if_foo_is_called();
    }

    if (bar()) {
        // Do not remove if something different from foo() is called.
        remove_this_call_if_foo_is_called();
    }
}

And I want to remove remove_this_call_if_foo_is_called() calls whenever they're in an if () body and the if condition has foo() call.

A Coccinelle example that unfortunately always removes these lines is:

@ rule1 @
@@
if (...) {
    ...
-   remove_this_call_if_foo_is_called();
    ...
}
Hi-Angel
  • 4,933
  • 8
  • 63
  • 86
  • In the past (~2010 IIRC) macros could be a problematic area for Coccinelle to parse. I don't know if that has changed since then, but I notice that you have a `NOT` macro defined -- have you tried contacting the developers or opening an issue on https://github.com/coccinelle/coccinelle ? – Morten Jensen Jun 29 '20 at 14:26
  • Looks like this could be a problem still per the discussion here from 2014 : https://github.com/coccinelle/coccinelle/issues/183 ? – Morten Jensen Jun 29 '20 at 14:38
  • @MortenJensen thanks! I should say, I was told on IRC that using `<+...` should work, it indeed it does. I.e. replacing the `if (...foo()...)` with `if (<+...foo()...+>)` makes it work. It is unclear though, why neither `...` nor `<...` works *(as I'm reading the docs, they should)*. Anyway… I'm waiting for the author to post the answer, they said they have SO account. – Hi-Angel Jun 29 '20 at 14:40

1 Answers1

1

I was told on IRC, the way to solve it is to surround foo() with <+... and ...+>. So, the working example is:

@ rule1 @
@@
if (<+...foo()...+>) {
    ...
-   remove_this_call_if_foo_is_called();
    ...
}

It is unclear though, why this works here, while the <... and ... variations doesn't. As I'm reading the docs any of them should work. This answer is a "community wiki", so feel free to edit it if you know why is that.

Hi-Angel
  • 4,933
  • 8
  • 63
  • 86