Clang Static Analyzer静态代码分析

学习自 深入剖析iOS编译

词法分析:

静态分析前会对diamante进行词法分析,生成Token,Token包括以下几类,

  • 关键字: 语法中的关键字 if、else、while for等
  • 标识符: 变量名
  • 字面量: 值、数字、字符串
  • 特殊符号: 加减乘除符号 clang -fmodules -E -Xclang -dump-tokens main.m 可以查看生成的token,其中还包括了代码位置等信息

语法分析

词法分析后进行语法分析,将token按照语法组合成语义生成ValDecl节点,将这些节点按照层级关系生成抽象语法树Abstract Syntax Tree(AST)

clang -fmodules -fsyntax-only -Xclang -ast-dump main.m

TranslationUnitDecl根节点开始,表示一个源文件
其中,Decl表示一个生命、Expr表示表达式、Literal表示特殊字面量、Stmt表示语句

静态分析原理

clang 静态分析是通过建立分析引擎和 checkers 所组成的架构,可以通过 clng --analyze命令调用

clang static analyzer分为analyzer core分析引擎和checker两部分,而所有的checker是基于底层的分析引擎之上的,也可以通过分析引擎提供的功能编写新的checker

如果想编写自己的checker,可以在 clang 项目的lib / StaticAnalyzer / Checkers目录下找到实例参考,比如 ObjCUnusedIVarsChecker.cpp 用来检查未使用定义过的变量。方便用户扩展对代码的检查规则或对bug类型的扩展,但是每执行完一条语句后,分析引擎就会会遍历所有checker中的回调函数,所以checker越多,速度越慢

通过clang -cc1 -analyzer-checker-help可以列出能调用的 checker

clang static analyzer引擎大致上分为CFG,MemRegion,SValBuilder,ConstraintManagerExplodedGraph 几个模块,clang static analyzer 本质上就是path-sensitive analysis,要很好的理解clang static analyzer引擎就需要对Data Flow Analysis有所了解,包括迭代数据流分析,path-sensitivepath-insensitiveflow-sensitive等。

编译的概念(词法->语法->语义->IR->优化->CodeGen)在 clang static analyzer 里到处可见,例如 Relaxed Live Variables Analysis 可以减少分析中的内存消耗,使用 mark-sweep 实现 Dead Symbols 的删除。

静态检查的一些库以及使用方法:
FauxPas_document_translation/README.md at master · DeveloperLx/FauxPas_document_translation · GitHub