《一种源代码中值计算错误的自动检测和定位方法.pdf》由会员分享,可在线阅读,更多相关《一种源代码中值计算错误的自动检测和定位方法.pdf(37页珍藏版)》请在专利查询网上搜索。
1、(10)申请公布号 CN 104298594 A (43)申请公布日 2015.01.21 CN 104298594 A (21)申请号 201410499170.9 (22)申请日 2014.09.25 G06F 11/36(2006.01) G06F 21/57(2013.01) (71)申请人 南京航空航天大学 地址 210016 江苏省南京市秦淮区御道街 29 号 (72)发明人 陈哲 朱云龙 魏欧 黄志球 (74)专利代理机构 南京瑞弘专利商标事务所 ( 普通合伙 ) 32249 代理人 杨晓玲 (54) 发明名称 一种源代码中值计算错误的自动检测和定位 方法 (57) 摘要 本发明。
2、公开了一种源代码中值计算错误的自 动检测和定位方法, 属于计算机软件测试领域, 该 方法利用编译器对源代码进行语法分析, 构造抽 象语法树, 通过遍历抽象语法树, 基于表达式类型 和用户指定检测的值计算错误类型, 判断是否存 在值计算错误的潜在风险 ; 对可能产生值计算错 误的表达式进行源代码变换, 加入值计算错误检 测和源代码定位的机制 ; 编译执行变换后的源代 码, 执行后的源代码程序会自动判断值计算错误 的发生, 并准确报告错误对应的源代码位置。 本方 法可以在软件运行过程中自动检测和定位软件中 的值计算错误, 以实现更准确的错误定位功能, 更 好的平台普适性, 更高的运行时性能和效率,。
3、 从而 克服现有的检测方法中存在的技术问题。 (51)Int.Cl. 权利要求书 11 页 说明书 24 页 附图 1 页 (19)中华人民共和国国家知识产权局 (12)发明专利申请 权利要求书11页 说明书24页 附图1页 (10)申请公布号 CN 104298594 A CN 104298594 A 1/11 页 2 1. 一种源代码中值计算错误的自动检测和定位方法, 其特征在于 : 利用编译器对源代 码进行语法分析, 构造抽象语法树, 通过遍历抽象语法树, 基于表达式类型和用户指定检测 的值计算错误类型, 判断是否存在值计算错误的潜在风险 ; 对可能产生值计算错误的表达 式进行源代码变换。
4、, 加入值计算错误检测和源代码定位的机制 ; 编译执行变换后的源代码, 执行后的源代码程序会自动判断值计算错误的发生, 并准确报告错误对应的源代码位置。 2. 根据权利要求 1 所述的源代码中值计算错误的自动检测和定位方法, 其特征在于 : 包括以下步骤 : 步骤 S1, 选择需要变换的源代码目录, 或者单个源代码文件 ; 步骤 S2, 指定需要检测的值计算错误类型 : 除数为 0、 值溢出、 变量使用前未初始化中 的一种或他们之间两种以上的组合 ; 步骤 S3, 将选择的源代码目录或文件复制到源代码变换的工作目录中 ; 步骤 S4, 对工作目录中的所有源文件进行宏扩展处理, 并保存扩展结果到。
5、相应的源文 件中 ; 步骤 S5, 遍历工作目录中的所有源文件, 利用编译器生成符号表和抽象语法树 ; 步骤S6, 如果指定需要检测的值计算错误类型中包括除数为0错误, 则进行除数为0错 误分析和源代码变换计算 ; 步骤 S7, 如果指定需要检测的值计算错误类型中包括值溢出错误, 则进行值溢出错误 分析和源代码变换计算 ; 步骤 S8, 如果指定需要检测的值计算错误类型中包括变量使用前未初始化错误, 则进 行变量使用前未初始化错误分析和源代码变换计算 ; 步骤 S9, 将步骤 S6、 S7 或 / 和 S8 中所有替换修改写回到相应的源文件中, 并根据本次 修改文件更新已处理文件列表 ; 步骤。
6、 S10, 将经过变换的源代码目录或源代码文件按原有方式进行编译, 生成可执行文 件 ; 步骤 S11, 将可执行文件部署在目标平台上并运行, 当出现值计算错误时, 插入的代码 可以自动检测到错误的发生, 并准确定位和报告值计算错误在源代码中的位置。 3. 根据权利要求 2 所述的源代码中值计算错误的自动检测和定位方法, 其特征在于 : 所述步骤 S4 中的宏扩展处理包括 : S41, 利用编译器的词法分析器对文件进行词法分析, 词法分析器返回经过宏扩展处理 之后的词法单元 ; S42, 针对扩展自宏的词法单元, 其属性中包括宏扩展之后的内容和宏扩展的位置, 用 扩展之后的内容替换宏扩展位置的。
7、原有内容。 4. 根据权利要求 3 所述的源代码中值计算错误的自动检测和定位方法, 其特征在于 : 所述步骤 S6 中除数为 0 错误分析和源代码变换计算的方法如下 : 利用函数调用, 在返回除 数给除法表达式之前, 对除数进行检查, 如果除数为 0, 则报告错误发生的源代码位置并结 束程序, 如果除数不为 0, 则正常地将除数返回给除法表达式。 5. 根据权利要求 4 所述的源代码中值计算错误的自动检测和定位方法, 其特征在于 : 所述步骤 S7 中值溢出错误分析和源代码变换计算的方法如下 : 将可能产生值溢出错误的 表达式的操作数进行类型提升, 然后将类型提升后的表达式值和原表达式值进行比。
8、较, 如 权 利 要 求 书 CN 104298594 A 2 2/11 页 3 果相同则说明未发生溢出, 将原表达式值返回, 如果不相同则说明发生溢出, 报告错误发生 的源代码位置并结束程序。 6. 根据权利要求 5 所述的源代码中值计算错误的自动检测和定位方法, 其特征在于 : 所述步骤 S8 中变量使用前未初始化错误分析和源代码变换计算的方法如下 : 记录每一个 非全局且声明时未赋初值的变量的赋值状态, 检查对于变量的引用, 如果是对变量的赋值, 则更新该变量的赋值状态记录, 如果是对变量值的使用, 则检查该变量的赋值状态记录, 未 赋值则表示出现变量使用前未初始化的错误, 已赋值则表示。
9、没有出现该错误。 7. 根据权利要求 6 所述的源代码中值计算错误的自动检测和定位方法, 其特征在于 : 所述步骤 S6 中除数为 0 错误分析和源代码变换计算的方法包括以下步骤 : 步骤 S61, 遍历编译器生成的抽象语法树, 如果当前节点 s 所在文件路径不在工作目录 下, 或已经存在于已处理文件列表中, 则忽略该节点, 不进行处理 ; 步骤 S6101, 如果当前节点 s 为除法表达式 a6101/b6101, 则从符号表中获取表达式 b6101 的类型 typeB6101, 然后将表达式 “a6101/b6101” 替换为如下函数调用 : a6101/(typeB6101)check_。
10、zero(b6101,fi leNameS,lineS,columnS) 其中 check_zero 为除 0 检测函数名, fi leNameS, lineS, columnS 分别为节点 s 所在文 件名, 行号和列号 ; 然后, 从抽象语法树中获得节点 s 所在文件的开始位置 locS, 加入到检 测函数声明插入位置集合 declLocSet, 表示此文件需要除 0 检测相关函数的声明 ; 步骤 S6102, 如果当前节点 s 为复合除赋值表达式 a6102/ b6102, 则从符号表中获取 表达式 b6102 的类型 typeB6102, 然后将表达式 “a6102/ b6102” 替。
11、换为如下函数调用 : a6102/ (typeB6102)check_zero(b6102,fi leNameS,lineS,columnS) 其中 check_zero 为除 0 检测函数名, fi leNameS, lineS, columnS 分别为节点 s 所在文 件名, 行号和列号 ; 然后, 从抽象语法树中获得节点 s 所在文件的开始位置 locS, 加入到检 测函数声明插入位置集合 declLocSet, 表示此文件需要除 0 检测相关函数的声明 ; 步骤 S62, 对于包含主函数声明的文件, 在文件开始位置插入检测函数 long double check_zero(long d。
12、ouble num,const char*fi leName,unsigned line,unsigned column)的 定义, 其中参数num代表除数, 参数fi leName, line, column分别代表运算发生位置所在文件 名, 行号和列号 ; 检测函数check_zero判断表示除数的参数num是否为0, 如果为0, 则报告 除 0 错误发生位置的文件名, 行号和列号, 并结束程序运行, 否则将除数作为函数的返回值 返回 ; 步骤 S63, 根据检测函数声明插入位置集合 declLocSet, 在相应位置插入检测 函数 long double check_zero(long 。
13、double num,const char*fileName,unsigned line,unsigned column) 的声明 ; 其中, 参数 num 代表除数, 参数 fi leName, line, column 分别代表运算发生位置所在文件名, 行号和列号 ; 然后, 将检测函数声明插入位置集合 declLocSet 重置为空。 8. 根据权利要求 7 所述的源代码中值计算错误的自动检测和定位方法, 其特征在于 : 所述步骤 S7 中值溢出错误分析和源代码变换计算的方法包括以下步骤 : 步骤 S71, 遍历编译器生成的抽象语法树, 如果当前节点 s 所在文件路径不在工作目录 下, 。
14、或已经存在于已处理文件列表中, 则忽略该节点, 不进行处理 ; 步骤S7101, 如果当前节点s为后自增表达式a7101+, 则从符号表中获取表达式a7101 权 利 要 求 书 CN 104298594 A 3 3/11 页 4 的类型 typeA7101 ; 如果 typeA7101 为指针类型, 则忽略节点 s, 不进行处理, 否则将表达式 “a7101+” 替换为如下逗号表达式 : (pOverflowTemp &(a7101), check_overflow(*(typeA7101*)pOverflowTemp+(typeA7101)1, *(typeA7101*)pOverflow。
15、Temp+(long double)1,fi leNameS,lineS,columnS), (*(typeA7101*)pOverflowTemp)+) 其中pOverflowTemp为空类型指针, 用来存储表达式a7101的地址, check_overflow为 值溢出检测函数名, fi leNameS, lineS, columnS 分别为节点 s 所在文件名, 行号和列号 ; 然 后, 从抽象语法树中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明插入位置 集合 declLocSet, 表示此文件需要值溢出检测相关函数的声明 ; 步骤S7102, 如果当前节点s为后自减。
16、表达式a7102-, 则从符号表中获取表达式a7102 的类型 typeA7102 ; 如果 typeA7102 为指针类型, 则忽略节点 s, 不进行处理, 否则将表达式 “a7102-” 替换为如下逗号表达式 : (pOverflowTemp &(a7102), check_overflow(*(typeA7102*)pOverflowTemp-(typeA7102)1, *(typeA7102*)pOverflowTemp-(long double)1,fi leNameS,lineS,columnS), (*(typeA7102*)pOverflowTemp)-) 其中pOverflo。
17、wTemp为空类型指针, 用来存储表达式a7102的地址, check_overflow为 值溢出检测函数名, fi leNameS, lineS, columnS 分别为节点 s 所在文件名, 行号和列号 ; 然 后, 从抽象语法树中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明插入位置 集合 declLocSet, 表示此文件需要值溢出检测相关函数的声明 ; 步骤S7103, 如果当前节点s为前自增表达式+a7103, 则从符号表中获取表达式a7103 的类型 typeA7103 ; 如果 typeA7103 为指针类型, 则忽略节点 s, 不进行处理, 否则将表达式 “。
18、+a7103” 替换为如下逗号表达式 : (pOverflowTemp &(a7103), check_overflow(*(typeA7103*)pOverflowTemp+(typeA7103)1, *(typeA7103*)pOverflowTemp+(long double)1,fi leNameS,lineS,columnS), (+(*(typeA7103*)pOverflowTemp) 其中pOverflowTemp为空类型指针, 用来存储表达式a7103的地址, check_overflow为 值溢出检测函数名, fi leNameS, lineS, columnS 分别为节点。
19、 s 所在文件名, 行号和列号 ; 然 后, 从抽象语法树中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明插入位置 集合 declLocSet, 表示此文件需要值溢出检测相关函数的声明 ; 步骤S7104, 如果当前节点s为前自减表达式a7104, 则从符号表中获取表达式a7104 的类型 typeA7104 ; 如果 typeA7104 为指针类型, 则忽略节点 s, 不进行处理, 否则将表达式 “-a7104” 替换为如下逗号表达式 : (pOverflowTemp &(a7104), check_overflow(*(typeA7104*)pOverflowTemp-(。
20、typeA7104)1, *(typeA7104*)pOverflowTemp-(long double)1,fi leNameS,lineS,columnS), (-(*(typeA7104*)pOverflowTemp) 权 利 要 求 书 CN 104298594 A 4 4/11 页 5 其中pOverflowTemp为空类型指针, 用来存储表达式a7104的地址, check_overflow为 值溢出检测函数名, fi leNameS, lineS, columnS 分别为节点 s 所在文件名, 行号和列号 ; 然 后, 从抽象语法树中获得节点 s 所在文件的开始位置 locS, 。
21、加入到检测函数声明插入位置 集合 declLocSet, 表示此文件需要值溢出检测相关函数的声明 ; 步骤 S7105, 如果当前节点 s 为取负表达式 -a7105, 则从符号表中获取表达式 a7105 的 类型 typeA7105, 将表达式 “-a7105” 替换为如下逗号表达式 : (overflowTemp1 (a7105), check_overflow(-(typeA7105)overflowTemp1, -overflowTemp1,fi leNameS,lineS,columnS), -(typeA7105)overflowTemp1) 其中 overflowTemp1 为 。
22、long double 类型变量, 用来记录表达式 a7105 的值, check_ overflow 为值溢出检测函数名, fi leNameS, lineS, columnS 分别为节点 s 所在文件名, 行号 和列号 ; 然后, 从抽象语法树中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明 插入位置集合 declLocSet, 表示此文件需要值溢出检测相关函数的声明 ; 步骤 S7106, 如果当前节点 s 为乘法表达式 a7106*b7106, 则从符号表中获取表达式 a7106 的类型 typeA7106, b7106 的类型 typeB7106, 将表达式 “a7。
23、106*b7106” 替换为如下逗 号表达式 : (overflowTemp1 (a7106), overflowStackPush(overflowTemp1), overflowTemp2 (b7106), overflowTemp1 overflowStackPop(), check_overflow(typeA7106)overflowTemp1*(typeB7106)overflowTemp2, overflowTemp1*overflowTemp2,fi leNameS,lineS,columnS), (typeA7106)overflowTemp1*(typeB7106)over。
24、flowTemp2) 其中 overflowTemp1 和 overflowTemp2 为 long double 类型变量, 分别用来记录表达 式 a7106 和表达式 b7106 的值, overflowStackPush 和 overflowStackPop 分别为栈结构的 压栈和出栈操作, check_overflow 为值溢出检测函数名, fi leNameS, lineS, columnS 分别 为节点 s 所在文件名, 行号和列号 ; 然后, 从抽象语法树中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明插入位置集合 declLocSet, 表示此文件需要值溢出检。
25、测相关函 数的声明 ; 步骤 S7107, 如果当前节点 s 为除法表达式 a7107/b7107, 则从符号表中获取表达式 a7107 的类型 typeA7107, b7107 的类型 typeB7107, 将表达式 “a7107/b7107” 替换为如下逗 号表达式 : (overflowTemp1 (a7107), overflowStackPush(overflowTemp1), overflowTemp2 (b7107), overflowTemp1 overflowStackPop(), check_overflow(typeA7107)overflowTemp1/(typeB71。
26、07)overflowTemp2, overflowTemp1/overflowTemp2,fi leNameS,lineS,columnS), 权 利 要 求 书 CN 104298594 A 5 5/11 页 6 (typeA7107)overflowTemp1/(typeB7107)overflowTemp2) 其中 overflowTemp1 和 overflowTemp2 为 long double 类型变量, 分别用来记录表达 式 a7107 和表达式 b7107 的值, overflowStackPush 和 overflowStackPop 分别为栈结构的 压栈和出栈操作, c。
27、heck_overflow 为值溢出检测函数名, fi leNameS, lineS, columnS 分别 为节点 s 所在文件名, 行号和列号 ; 然后, 从抽象语法树中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明插入位置集合 declLocSet, 表示此文件需要值溢出检测相关函 数的声明 ; 步骤 S7108, 如果当前节点 s 为加法表达式 a7108+b7108, 则从符号表中获取表达式 a7108 的类型 typeA7108, b7108 的类型 typeB7108 ; 如果 typeA7108 或 typeB7108 为指针类 型, 则忽略节点 s, 不进行。
28、处理, 否则将表达式 “a7108+b7108” 替换为如下逗号表达式 : (overflowTemp1 (a7108), overflowStackPush(overflowTemp1), overflowTemp2 (b7108), overflowTemp1 overflowStackPop(), check_overflow(typeA7108)overflowTemp1+(typeB7108)overflowTemp2, overflowTemp1+overflowTemp2,fi leNameS,lineS,columnS), (typeA7108)overflowTemp1+(t。
29、ypeB7108)overflowTemp2) 其中 overflowTemp1 和 overflowTemp2 为 long double 类型变量, 分别用来记录表达 式 a7108 和表达式 b7108 的值, overflowStackPush 和 overflowStackPop 分别为栈结构的 压栈和出栈操作, check_overflow 为值溢出检测函数名, fi leNameS, lineS, columnS 分别 为节点 s 所在文件名, 行号和列号 ; 然后, 从抽象语法树中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明插入位置集合 declLocSet。
30、, 表示此文件需要值溢出检测相关函 数的声明 ; 步骤 S7109, 如果当前节点 s 为减法表达式 a7109-b7109, 则从符号表中获取表达式 a7109 的类型 typeA7109, b7109 的类型 typeB7109 ; 如果 typeA7109 或 typeB7109 为指针类 型, 则忽略节点 s, 不进行处理, 否则将表达式 “a7109-b7109” 替换为如下逗号表达式 : (overflowTemp1 (a7109), overflowStackPush(overflowTemp1), overflowTemp2 (b7109), overflowTemp1 ove。
31、rflowStackPop(), check_overflow(typeA7109)overflowTemp1-(typeB7109)overflowTemp2, overflowTemp1-overflowTemp2,fi leNameS,lineS,columnS), (typeA7109)overflowTemp1-(typeB7109)overflowTemp2) 其中 overflowTemp1 和 overflowTemp2 为 long double 类型变量, 分别用来记录表达 式 a7109 和表达式 b7109 的值, overflowStackPush 和 overflo。
32、wStackPop 分别为栈结构的 压栈和出栈操作, check_overflow 为值溢出检测函数名, fi leNameS, lineS, columnS 分别 为节点 s 所在文件名, 行号和列号 ; 然后, 从抽象语法树中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明插入位置集合 declLocSet, 表示此文件需要值溢出检测相关函 数的声明 ; 权 利 要 求 书 CN 104298594 A 6 6/11 页 7 步骤S7110, 如果当前节点s为位左移表达式a7110b7111, 则从符号表中获取表达式 a7111 的类型 typeA7111, b7111 的。
33、类型 typeB7111, 将表达式 “a7111b7111” 替换为如下 逗号表达式 : (overflowTemp1 (a7111), overflowStackPush(overflowTemp1), overflowTemp2 (b7111), overflowTemp1 overflowStackPop(), check_overflow(typeA7111)overflowTemp1(typeB7111)overflowTemp2, (long long int)overflowTemp1(long long int)overflowTemp2, fi leNameS,lineS,。
34、columnS), (typeA7111)overflowTemp1(typeB7111)overflowTemp2) 其中 overflowTemp1 和 overflowTemp2 为 long double 类型变量, 分别用来记录表达 式 a7111 和表达式 b7111 的值, overflowStackPush 和 overflowStackPop 分别为栈结构的 压栈和出栈操作, check_overflow 为值溢出检测函数名, fi leNameS, lineS, columnS 分别 为节点 s 所在文件名, 行号和列号 ; 然后, 从抽象语法树中获得节点 s 所在文件的开。
35、始位置 locS, 加入到检测函数声明插入位置集合 declLocSet, 表示此文件需要值溢出检测相关函 数的声明 ; 步骤 S7112, 如果当前节点 s 为复合乘赋值表达式 a7112* b7112, 则从符号表中获取 表达式 a7112 的类型 typeA7112, b7112 的类型 typeB7112, 将表达式 “a7112* b7112” 替 换为如下逗号表达式 : (pOverflowTemp &(a7112), overflowStackPush(long)pOverflowTemp), 权 利 要 求 书 CN 104298594 A 7 7/11 页 8 overflo。
36、wTemp1 (b7112), pOverflowTemp (void*)(long)overflowStackPop(), check_overflow(typeA7112)(*(typeA7112*)pOverflowTemp)* (typeB7112)overflowTemp1),(*(typeA7112*)pOverflowTemp)*overflowTemp1, fi leNameS,lineS,columnS), (*(typeA7112*)pOverflowTemp)* (typeB7112)overflowTemp1) 其中 pOverflowTemp 为空类型指针, 用来存储。
37、表达式 a7112 的地址, overflowTemp1 为 long double 类 型 变 量,用 来 记 录 表 达 式 b7112 的 值, overflowStackPush 和 overflowStackPop 分别为栈结构的压栈和出栈操作, check_overflow 为值溢出检测函数 名, fi leNameS, lineS, columnS 分别为节点 s 所在文件名, 行号和列号 ; 然后, 从抽象语法树 中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明插入位置集合 declLocSet, 表示此文件需要值溢出检测相关函数的声明 ; 步骤 S7113,。
38、 如果当前节点 s 为复合除赋值表达式 a7113/ b7113, 则从符号表中获取 表达式 a7113 的类型 typeA7113, b7113 的类型 typeB7113, 将表达式 “a7113/ b7113” 替 换为如下逗号表达式 : (pOverflowTemp &(a7113), overflowStackPush(long)pOverflowTemp), overflowTemp1 (b7113), pOverflowTemp (void*)(long)overflowStackPop(), check_overflow(typeA7113)(*(typeA7113*)pOve。
39、rflowTemp)/(typeB7113) overflowTemp1),(*(typeA7113*)pOverflowTemp)/overflowTemp1, fi leNameS,lineS,columnS), (*(typeA7113*)pOverflowTemp)/ (typeB7113)overflowTemp1) 其中 pOverflowTemp 为空类型指针, 用来存储表达式 a7113 的地址, overflowTemp1 为 long double 类 型 变 量,用 来 记 录 表 达 式 b7113 的 值, overflowStackPush 和 overflowSt。
40、ackPop 分别为栈结构的压栈和出栈操作, check_overflow 为值溢出检测函数 名, fi leNameS, lineS, columnS 分别为节点 s 所在文件名, 行号和列号 ; 然后, 从抽象语法树 中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明插入位置集合 declLocSet, 表示此文件需要值溢出检测相关函数的声明 ; 步骤 S7114, 如果当前节点 s 为复合加赋值表达式 a7114+ b7114, 则从符号表中获取 表达式 a7114 的类型 typeA7114, b7114 的类型 typeB7114 ; 如果 typeA7114 或 t。
41、ypeB7114 为指针类型, 则忽略节点 s, 不进行处理, 否则将表达式 “a7114+ b7114” 替换为如下逗号 表达式 : (pOverflowTemp &(a7114), overflowStackPush(long)pOverflowTemp), overflowTemp1 (b7114), pOverflowTemp (void*)(long)overflowStackPop(), check_overflow(typeA7114)(*(typeA7114*)pOverflowTemp)+ (typeB7114)overflowTemp1), 权 利 要 求 书 CN 104。
42、298594 A 8 8/11 页 9 (*(typeA7114*)pOverflowTemp)+overflowTemp1,fi leNameS,lineS,columnS), (*(typeA7114*)pOverflowTemp)+ (typeB7114)overflowTemp1) 其中 pOverflowTemp 为空类型指针, 用来存储表达式 a7114 的地址, overflowTemp1 为 long double 类 型 变 量,用 来 记 录 表 达 式 b7114 的 值, overflowStackPush 和 overflowStackPop 分别为栈结构的压栈和出栈。
43、操作, check_overflow 为值溢出检测函数 名, fi leNameS, lineS, columnS 分别为节点 s 所在文件名, 行号和列号 ; 然后, 从抽象语法树 中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明插入位置集合 declLocSet, 表示此文件需要值溢出检测相关函数的声明 ; 步骤 S7115, 如果当前节点 s 为复合减赋值表达式 a7115- b7115, 则从符号表中获取 表达式 a7115 的类型 typeA7115, b7115 的类型 typeB7115 ; 如果 typeA7115 或 typeB7115 为指针类型, 则忽略。
44、节点 s, 不进行处理, 否则将表达式 “a7115- b7115” 替换为如下逗号 表达式 : (pOverflowTemp &(a7115), overflowStackPush(long)pOverflowTemp), overflowTemp1 (b7115), pOverflowTemp (void*)(long)overflowStackPop(), check_overflow(typeA7115)(*(typeA7115*)pOverflowTemp)- (typeB7115)overflowTemp1), (*(typeA7115*)pOverflowTemp)-overfl。
45、owTemp1,fi leNameS,lineS,columnS), (*(typeA7115*)pOverflowTemp)- (typeB7115)overflowTemp1) 其中 pOverflowTemp 为空类型指针, 用来存储表达式 a7115 的地址, overflowTemp1 为 long double 类 型 变 量,用 来 记 录 表 达 式 b7115 的 值, overflowStackPush 和 overflowStackPop 分别为栈结构的压栈和出栈操作, check_overflow 为值溢出检测函数 名, fi leNameS, lineS, colum。
46、nS 分别为节点 s 所在文件名, 行号和列号 ; 然后, 从抽象语法树 中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明插入位置集合 declLocSet, 表示此文件需要值溢出检测相关函数的声明 ; 步骤 S7116, 如果当前节点 s 为复合位左移赋值表达式 a7116 b7117, 则从符号表 中获取表达式 a7117 的类型 typeA7117, b7117 的类型 typeB7117, 将表达式 “a7117 b7117” 替换为如下逗号表达式 : (pOverflowTemp &(a7117), overflowStackPush(long)pOverflowT。
47、emp), overflowTemp1 (b7117), pOverflowTemp (void*)(long)overflowStackPop(), check_overflow(typeA7117)(*(typeA7117*)pOverflowTemp) (typeB7117)overflowTemp1),(long long int)(*(typeA7117*)pOverflowTemp) (long long int)overflowTemp1,fi leNameS,lineS,columnS), (*(typeA7117*)pOverflowTemp) (typeB7117)over。
48、flowTemp1) 其中 pOverflowTemp 为空类型指针, 用来存储表达式 a7117 的地址, overflowTemp1 为 long double 类 型 变 量,用 来 记 录 表 达 式 b7117 的 值, overflowStackPush 和 overflowStackPop 分别为栈结构的压栈和出栈操作, check_overflow 为值溢出检测函数 名, fi leNameS, lineS, columnS 分别为节点 s 所在文件名, 行号和列号 ; 然后, 从抽象语法树 中获得节点 s 所在文件的开始位置 locS, 加入到检测函数声明插入位置集合 dec。
49、lLocSet, 表示此文件需要值溢出检测相关函数的声明 ; 步 骤 S7118, 如 果 当 前 节 点 s 为 隐 含 转 换 表 达 式 (typeCast7118)a7118, 其 中 typeCast7118 为隐含转换类型, 则从符号表中获取表达式 a7118 的类型 typeA7118 ; 如果 typeA7118和typeCast7118相同, 忽略节点s, 不进行处理, 否则将表达式 “(typeCast7118) a7118” 替换为如下逗号表达式 : (overflowTemp1 (a7118), check_overflow(typeCast7118)overflowTemp1, overflowTemp1,fi leNameS,lineS,columnS), (typeCast7118)overflowTemp1) 其中 overflowTemp1 为 long double 类型变量, 用来记录表达式 a7118 的值, check_ overflow 为值溢出。