使用clang匹配器来检测模式序列

Meh*_* EP 7 c matcher clang abstract-syntax-tree llvm-clang

是否可以使用clang匹配器来识别程序中的模式序列?

例如,我需要找到pattern1在pattern2之前发生的情况.

例如:

Pattern1 =为指针P
pattern2 =取消引用指针P赋值

我可以识别出代码中出现pattern1和pattern2的情况,但是可以指定一个排序吗?(假设pattern1必须在pattern2之前发生并且只匹配那些情况)谢谢!

Ahm*_*sud 3

正确答案

\n\n

实际上,遍历 AST 进行序列模式(这是静态分析的基础)并不是真正正确的方法,因为你不知道该语句是否pattern1真的会在之前发生pattern2

\n\n

考虑

\n\n
 int foo() {\n       int a = 0;\n       int *b;\n       int c = -1;\n       if(c < 0) goto fixit;\n nowhat:\n       b = &a;\n fixit: \n       c = *b;\n       goto nowhat;\n }\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如您所看到的,AST 在这里没有帮助,但 CFG 是正确的使用方法。

\n\n

有点使用 AST 的答案

\n\n

如果您查看 AST (v6.0.0) 中的遍历匹配器,它们本质上几乎是分层的。您正在寻求扩展匹配来寻找兄弟姐妹。

\n\n

我即将介绍的大部分内容都假设您知道如何实现自定义 AST 匹配器。如果没有,Manu S\xc3\xa1nchez 在他的为libclang编写 AST 匹配器博客文章中对此进行了很好的解释。

\n\n

不确定他是否真正开始编写兄弟匹配器,但他非常接近它,所以从那里开始,然后你必须实现类似于此的东西:

\n\n

假设给定代码:

\n\n
  class P {}; class Q {}; class R {};\n
Run Code Online (Sandbox Code Playgroud)\n\n

我们希望能够做这样的事情:

\n\n
 (matcher = recordDecl(hasName("P"), \\\n        hasNextSibling(recordDecl(hasName("R"))))`\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以在类中组合matchesChildand并遍历当前光标的父级的子级(这些将是同级:P)。请阅读脚注,因为您必须实现 BoundCursors 以避免失控递归。matchesParentAstMatchFinder

\n