Coccinelle 规则匹配 if 中的 foo() 调用

Coccinelle rule to match foo() call inside an if

所以,我偶然发现的问题是 if 中的代码可能非常复杂,它可能是 if (NOT(ret = foo()))if (foo() == NULL) 之类的东西,并且其他变体也是可能的。

对我来说,明显的答案是规则行 if (...foo()...),但 Coccinelle 说它无法解析它。

我尝试了我设法找到或猜测的一切,到目前为止都无济于事。


作为演示示例,这里有一个 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();
    }
}

我想删除 remove_this_call_if_foo_is_called() 调用,只要它们在 if () 正文中并且 if 条件有 foo() 调用。

一个不幸的是总是删除这些行的 Coccinelle 示例是:

@ rule1 @
@@
if (...) {
    ...
-   remove_this_call_if_foo_is_called();
    ...
}

我在IRC上被告知,解决方法是用<+......+>包围foo()。因此,工作示例是:

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

虽然不清楚,为什么它在这里起作用,而 <...... 变体却不起作用。在我阅读 the docs 时,它们中的任何一个都应该有效。这个答案是一个“社区维基”,所以如果你知道为什么会这样,请随时编辑它。