已关闭
【缺陷报告】除零错误 - 文件cast.h - 函数CastExtendWithMaskMode - 行号170 #255
zhangjunkai9创建于  22 天前关闭于  4 天前
zhangjunkai9
22 天前 创建

缺陷信息

缺陷类型divideByZero (除零错误)
函数CastExtendWithMaskMode
文件autofuse/ascendc/api/cast.h
行号170
置信度90%

缺陷描述

在 CastExtendWithOneTransferWithMaskMode 函数中,第235-236行声明了局部变量 max_dtype_size_between_src_and_mid=0 和 max_dtype_size_between_mid_and_dst=0。随后第242-247行的 if-constexpr 块内重新声明了同名局部变量(带 uint32_t 类型前缀),形成变量遮蔽(variable shadowing),导致外层变量始终保持初始值0。这些0值在第249行和第252行作为 dtype_size 参数传入 CastExtendWithMaskMode,在第170行执行 ONE_REPEAT_BYTE_SIZE(256) / dtype_size(0) 时触发整数除零(未定义行为,通常导致程序崩溃)。该代码路径在 CastExtend 被 int64_t<->half 类型组合实例化时被触发,CastExtend 通过 cast_api_call.cpp 的代码生成路径可达。

事实核查

经复核确认:缺陷模式成立(1)——CastExtendWithOneTransferWithMaskMode 第235-236行声明外层变量 max_dtype_size_between_src_and_mid=0 和 max_dtype_size_between_mid_and_dst=0,第243-244行和第246-247行在 if-constexpr 块内以 uint32_t 类型前缀重新声明同名局部变量,形成变量遮蔽(variable shadowing),外层变量始终保持初始值0;第249、252行将外层0值作为 dtype_size 传入 CastExtendWithMaskMode,第170行 ONE_REPEAT_BYTE_SIZE(256)/dtype_size(0) 触发整数除零。
防护无效(2):第170行无除零保护。
函数可达(3):CastExtend 7参版本第279行调用 CastExtendWithOneTransferWithMaskMode,由 cast_api_call.cpp 代码生成路径调用。
触发可满足(4):EnableCastMaskModeOptimize(cast_api_call.cpp:29-43)第39行显式列出 {"int64_t","half"} 和 {"half","int64_t"} 为支持的转换组合,返回 true 时生成7参 CastExtend 调用(第97-118行),数据流 source(第235行)→sink(第170行)各节点经 Read 逐行验证属实,确凿可触发。

数据流证据

Source(问题源头)

autofuse/ascendc/api/cast.h:235 行 uint32_t max_dtype_size_between_src_and_mid = 0 外层变量初始化为0(本应为8或4,但因遮蔽未赋值)

Sink(问题爆发点)

autofuse/ascendc/api/cast.h:170 行 uint32_t elem_in_one_repeat = ONE_REPEAT_BYTE_SIZE / dtype_size 当 dtype_size=0 时整数除零(ONE_REPEAT_BYTE_SIZE 为常量256)

传播路径:

# 文件 行号 说明
1 autofuse/ascendc/api/cast.h 235 uint32_t max_dtype_size_between_src_and_mid = 0 外层变量初始化为0
2 autofuse/ascendc/api/cast.h 236 uint32_t max_dtype_size_between_mid_and_dst = 0 外层变量初始化为0
3 autofuse/ascendc/api/cast.h 243 uint32_t max_dtype_size_between_src_and_mid = 8 if-constexpr块内声明新局部变量,遮蔽外层变量(应为赋值而非声明)
4 autofuse/ascendc/api/cast.h 244 uint32_t max_dtype_size_between_mid_and_dst = 4 if-constexpr块内声明新局部变量,遮蔽外层变量
5 autofuse/ascendc/api/cast.h 249 CastExtendWithMaskMode<InT, float>(..., max_dtype_size_between_src_and_mid, ...) 传入外层变量值0作为dtype_size
6 autofuse/ascendc/api/cast.h 252 CastExtendWithMaskMode<float, OutT>(..., max_dtype_size_between_mid_and_dst, ...) 传入外层变量值0作为dtype_size
7 autofuse/ascendc/api/cast.h 170 uint32_t elem_in_one_repeat = ONE_REPEAT_BYTE_SIZE / dtype_size 即 256/0 整数除零(sink)

修复建议

在 CastExtendWithOneTransferWithMaskMode 函数的第242-248行,移除 if-constexpr 块内变量的 uint32_t 类型前缀,将其从声明改为赋值:

    if constexpr (AscendC::IsSameType<InT, int64_t>::value) {
      max_dtype_size_between_src_and_mid = 8;
      max_dtype_size_between_mid_and_dst = 4;
    } else {
      max_dtype_size_between_src_and_mid = 4;
      max_dtype_size_between_mid_and_dst = 8;
    }
likedislike
wangmingming成员
22 天前 评论:

你好,感谢建议, 后续分析处理

likedislike
Wwangmingming成员
22 天前 将 gcw_V3YyYBt1 设为负责人
Jjcmrn0930
15 天前 关联了pull request:解决issue253 254 255
Jjcmrn0930
15 天前 关联了pull request:解决issue 253 254 255
Wwangmingming成员
4 天前 issue状态由 进行中 改变为 已完成
Wwangmingming成员
4 天前 关闭了 issue