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,ConstraintManager
和 ExplodedGraph
几个模块,clang static analyzer
本质上就是path-sensitive analysis
,要很好的理解clang static analyzer
引擎就需要对Data Flow Analysis
有所了解,包括迭代数据流分析,path-sensitive
,path-insensitive
,flow-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