像下面这样的变换,当某物是
func_1(&something->field)
时适用于 foo_t
,但不能捕获 v 本身是一个字段(例如 func_1(&something->v->field)
)的情况
@@
typedef foo_t;
foo_t *v;
@@
- func_1(&v->field)
+ func_2(v)
另一方面,如果我使用这样的表达式:
@@
expression v;
@@
- func_1(&v->field)
+ func_2(v)
它可以工作,但过于急切,可能会匹配类型不是
foo_t
的情况,只是因为某些其他类型具有相同的字段名称。
有没有办法获得表达式的匹配,但将表达式类型限制为
foo_t
?
由于这是结构的字段,因此您可以创建单独的规则来匹配该结构,然后继承该规则。然后,第一条规则会将任意结构与正确类型的字段相匹配:
@match exists@
typedef foo_t;
identifier fld;
identifier StructName;
@@
struct StructName { ...
foo_t fld;
...
};
然后将该字段继承到您想要使用的规则中:
@@
expression v;
identifier match.fld;
@@
- func_1(&v->fld)
+ func_2(v)
使用以下示例代码(我在其中创建了一个嵌套结构以获得更通用的表达式):
typedef int foo_t;
extern void func_1(foo_t *ptr);
struct Nested {
foo_t one;
};
struct Example {
struct Nested *inner;
};
int foo(struct Example *ptr) {
for (int i = 0; i < 10; ++i) {
func_1(&(&ptr[i])->inner->one);
}
return 1;
}
int bar(struct Nested *ptr) {
for (int i = 0; i < 10; ++i) {
func_1(&ptr->one);
}
return 1;
}
你得到这个结果:
$ spatch --sp-file field-type.cocci code/field-type.c
init_defs_builtins: /usr/lib/coccinelle/standard.h
HANDLING: code/field-type.c
diff =
--- code/field-type.c
+++ /tmp/cocci-output-210347-f4f050-field-type.c
@@ -12,14 +12,14 @@ struct Example {
int foo(struct Example *ptr) {
for (int i = 0; i < 10; ++i) {
- func_1(&(&ptr[i])->inner->one);
+ func_2((&ptr[i])->inner);
}
return 1;
}
int bar(struct Nested *ptr) {
for (int i = 0; i < 10; ++i) {
- func_1(&ptr->one);
+ func_2(ptr);
}
return 1;
}