An Automatic Testing Approach for Compiler Based on Metamorphic Testing Technique
介绍
现有的问题及方法
- Oracle的生成
- 基于参考的方法
- 需要高度可靠的参考编译器
- 基于断言的方法
- 将断言添加到源程序中,以检查断言点的行为是否与程序语义一致
- Back-to-back approach
- 不同团队并行开发多个版本编译器,并检查多个版本之间的一致性
- Based on compiler’s simulators
- 基于参考的方法
背景知识
- 编译器测试
- 编译器的工作原理:对源程序进行语义语法分析 → \rightarrow → 中间代码的合成 → \rightarrow → 优化 → \rightarrow → 生成目标可执行文件
- 正确性依赖的环节:语言完整 ∧ \land ∧ 语义健全 ∧ \land ∧ 优化有效
编译器的自动变质测试框架
使用的变质关系
- Equivalence preservation relation
生成等价测试程序方法
- 基本原则
- 等价类型
- 表达式等价
- 语句或结构块等价
- 思路
- 具有相同控制结构的复合等效程序组件可以产生更大规模的等效组件
- General control flow graph (GCFG)
- 具有相同控制结构的复合等效程序组件可以产生更大规模的等效组件
- 等价类型
等效表达式的构造
等效赋值块的建造
-
由一系列赋值语句组成
-
提出了一种基于数据依赖概念生成等效赋值块的方法
-
定义了赋值语句依赖关系
- 假设语句
S
2
S_2
S2可从
S
1
S_1
S1到达,如果
S
1
S_1
S1和
S
2
S_2
S2都可以访问同一个变量并且至少一个访问为写入,则
S
2
S_2
S2依赖于
S
1
S_1
S1,记为
S
1
δ
S
2
S_1 \delta S_2
S1δS2
- 假设语句 S 1 S_1 S1写变量而 S 2 S_2 S2读变量,则 S 2 S_2 S2 flow-depends on S 1 S_1 S1,记为 S 1 δ f S 2 S_1 \delta^f S_2 S1δfS2
- 假设语句 S 1 S_1 S1读变量而 S 2 S_2 S2写变量,则 S 2 S_2 S2 anti-depends on S 1 S_1 S1,记为 S 1 δ a S 2 S_1 \delta^a S_2 S1δaS2
- 假设语句
S
1
S_1
S1和
S
2
S_2
S2同写变量,则
S
2
S_2
S2 output-depends on
S
1
S_1
S1,记为
S
1
δ
o
S
2
S_1 \delta^o S_2
S1δoS2
- 假设语句
S
2
S_2
S2可从
S
1
S_1
S1到达,如果
S
1
S_1
S1和
S
2
S_2
S2都可以访问同一个变量并且至少一个访问为写入,则
S
2
S_2
S2依赖于
S
1
S_1
S1,记为
S
1
δ
S
2
S_1 \delta S_2
S1δS2
-
等效赋值块的生成:
- 赋值块的等效定义:如果两个赋值块由相同的语句组成,并且语句之间的数据依赖性也相同,那么这两个块是等效的。
- 具体生成方法:
- 随机生成一个依赖图
- 用赋值语句进行填充
- 对依赖图进行拓扑排序
- 从拓扑序列中派生赋值块
等效子模块的构建
- 在循环或分支中的语句
- 提出了一种基于经典优化原理的等效子模块生成方法:消除无用代码、消除通用子表达式、循环不变量
- 具体方式
- 生成一个控制流程图
- 根据特定经典优化原理,在图表中选择一定数量的节点作为“可优化”节点,用“可优化”和“优化”语句填充节点,从聚焦节点向前或向后遍历路径,同时在具有特定属性的路径上标记节点,这些属性指定引用属性或定义某些变量;
- 根据标记属性用具体语句填充CFG的节点;
- 遍历CFG,导出“优化”子模块及其“优化”版本。
实验和应用
Mettoc
- Mutation Experiments
- Open-source Compilers
- GCC(1)、PCC、TCC、UCC(1)