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

时间:2016-05-25 05:57:52

标签: c clang abstract-syntax-tree llvm-clang matcher

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

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

例如:

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

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

1 个答案:

答案 0 :(得分:1)

正确答案

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

考虑

 int foo() {
       int a = 0;
       int *b;
       int c = -1;
       if(c < 0) goto fixit;
 nowhat:
       b = &a;
 fixit: 
       c = *b;
       goto nowhat;
 }

正如你所看到的,AST在这方面没有帮助,但CFG是正确的选择。

使用AST

的答案

如果你看一下AST中的Traversal Matchers(v6.0.0),它们本质上是等级的。您正在寻找扩展匹配以寻找兄弟姐妹。

我将要介绍的大部分内容假定您知道如何实现自定义AST匹配器。如果没有,ManuSánchez在他的Writing AST Matchers for libclang博客文章中解释得非常好。

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

让我们说代码:

  class P {}; class Q {}; class R {};

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

 (matcher = recordDecl(hasName("P"), \
        hasNextSibling(recordDecl(hasName("R"))))`

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