已合并
fix(chir): pass source location to VARRAY_GET in compound assign to avoid ICE #1934
fix(chir): pass source location to VARRAY_GET in compound assign to avoid ICE #1934
已合并
wangyinqiang创建于 7月17日
wangyinqiang
wangyinqiang仓颉Committer
7月17日

变更内容(必填)

修复 cjc 编译 ICE(Internal Compiler Error: begin of range is zero, error code 12)。

问题:在 TranslateVArrayAssign 中,复合赋值运算符(+=-=&=^=|= 等普通复合赋值,以及走短路分支的 &&=||=)的左侧 VARRAY_GET intrinsic 创建时未传递源码位置(source location)。只要 CHIR 能把该下标判定为越界常量,越界诊断就会在零 DebugLocation 上发射,进而在 DiagnosticEngineImpl::CheckRange 触发 InternalError

触发条件不限于 -O2

  • 不加任何优化选项:下标是普通局部变量(如 var b = 4; test[b] |= 1)时,ConstAnalysis 即可判定越界并发射诊断 → ICE。
  • -O2:下标经常量传播折叠(如 issue 中 m[42 / getSize<Int64>()] |= 42 这种 const func 运算)后,由 RangePropagation 发射诊断 → ICE。

两条路径共用同一个缺失 loc 的 VARRAY_GET,故一行修复同时覆盖。

修复:在 TranslateAssignExpr.cpp:86CreateAndAppendExpression<Intrinsic> 调用补上 loc 首参,使其与同文件 :113CreateAndAppendVArraySet 的模式一致。修复后复合赋值越界下标由 ICE 改为正常诊断 "array index is out of bounds" 并指向赋值表达式源码位置。

关于位置参数的选择:VARRAY_GET 传的是 loc(整条 AssignExpr)而非上方第 81 行算好却未使用的 baseLoc,这是有意的——用 loc 才能与同一条复合赋值生成的 VARRAY_SET 同址,两条内容相同的越界诊断被 DiagnosticEngine 去重成一条;若改用 baseLoc,同一条语句会报两条重复诊断。(baseLoc 是既有死变量,属无关改动,未在本 PR 中清理。)

行为变化说明:修复前,VArray 复合赋值越界下标触发 ICE(exit=2);修复后,输出正常诊断错误并以 exit=1 正常退出。这是从非法行为到正确诊断的改善,非回归。

同类问题排查src/CHIR 下其余 CreateAndAppendExpression<Intrinsic> 调用已核对——VArray 读路径(TranslateSubscriptExpr.cpp:115)本来就传了 loc(本地实测读越界下标在修复前后都能正常诊断,不受影响);剩余未传 loc 的只有 PREINITIALIZEGlobalVarInitializer.cpp:701)和 BEGIN_CATCHTranslateTryExpr.cpp:149,以及 TranslateForInExpr.cpp:551 与其 #else 非 CJNATIVE 后端分支 :553)这类编译器生成节点,本身没有对应用户源码位置,也不参与范围检查诊断。因此本 PR 一行改动即覆盖该 ICE 的全部触发路径。

回归用例:配套用例在 https://gitcode.com/Cangjie/cangjie_test/pulls/2021 (同一 issue 关联,多仓联合门禁)。

详见:https://gitcode.com/Cangjie/UsersForum/issues/3351

变更类型(必填)

变更内容自检(必填)

平台差异情况:

影响组件:

编译本地自验证结果:

测试用例本地自验证结果:

验证情况:

  • -O2 复现用例(Issue 原样):修复前 ICE exit=2,修复后正确诊断 "array index is out of bounds" + exit=1
  • 不开优化选项、下标为普通变量(var b = 4; test[b] |= 1):修复前同样 ICE exit=2(诊断由 ConstAnalysis 发射),修复后正确诊断 "array index 4 is past the end of array" + exit=1
  • 新增回归用例(cangjie_test!2021),三个新增用例同在 LLT/compiler/CHIR/ConstantSafetyCheck/VArrayIndexOutOfBounds/,与漏掉本缺陷的既有用例 varrayAsg01.cj 并列:
    • varrayAsg02.cj:不依赖优化选项,下标为普通变量,覆盖 ConstAnalysis 发射路径与 TranslateVArrayAssign 三个分支(|=+= 普通复合赋值;&&= AND_ASSIGN;||= OR_ASSIGN),/* SCAN */ 逐字符比对 4 条诊断
    • varrayAsg03.cj / varrayAsg04.cj%enableO2 折叠 const func 下标后由 RangePropagation 报出,分别对应越上界 / 越下界,/* SCAN */ 比对诊断位置与文本
    • 本地 mac_aarch64、--level=0:目录内 5 个用例全 PASS;换用修复前的 cjc,三个新增用例均 FAIL;变异测试(改期望行号 / 改 range 数值 / 去掉 %enableO2)均 FAIL,确认断言非空转

关联的issue(必填)

https://gitcode.com/Cangjie/UsersForum/issues/3351

likedislike
Pull Request已成功合入, 合并人@cangjie-ci
(感谢 wangyinqiang 的贡献)
wangyinqiangwangyinqiang仓颉Committer
7月17日 关联了issue:【缺陷】cjc -O2 编译 ICE (begin of range is zero)
仓颉编程语言
仓颉编程语言成员
7月17日 评论:

PR创建成功通知 | 感谢您的贡献 🎉

您好!系统已检测到您成功创建 Pull Request(PR),感谢您对项目的支持与参与!以下几点需要您着重关注:

一、PR必须关联Issue ❗️

触发门禁检查的必要步骤:在PR描述框输入Issue完整链接,完成Issue关联

请注意,一个 Issue 不能同时关联同一 base 仓库内同一个分支的多个开启状态的 PR

二、门禁触发规则 🔧

  1. 门禁类型判定:由Issue关联的PR所属代码仓数量决定
    • 关联多个代码仓PR:触发「多仓联合门禁」
    • 关联单个代码仓PR:触发「单仓门禁」
  2. 启动指令与检查范围:需主动回复指令:
    • 回复 "start build":执行Cangjie的主要基础检查,包含commit格式检查、静态告警分析、OAT开源声明检查、多平台构建、单元/集成测试等
    • 关联同一issue的多个PR,仅需在任意一个PR里回复触发一次门禁,该PR门禁通过后,所有PR都会添加Label和测试人
    • 每个pr只能同时运行一条CI流水线,如需重新启动,请先关闭运行中的,再评论触发门禁
    • Markdown修改仅触发文档类构建测试门禁,不会触发Cangjie的编译测试门禁
    • commit 信息格式请遵循:Conventional Commits 规范
    • 请保证每一条 commit 都已添加 Signed-Off-By 信息

三、合入条件 ⚠️

  • 满足最低评审人数,且评审问题需全部解决;
  • 禁止合入本人创建的PR,需由其他协作者操作;
  • 合并前确保关联流水线任务运行成功(build-test-passed)。

四、合并PR ✅

回复 "start merge",CI流水线会自动检查所有关联PR的状态、版本号标签、检视意见密度、兼容性,若所有PR都满足合并条件,则将会同时合并所有PR。若存在不满足合并条件的PR,则不会合并任何PR。

如果希望不进行兼容性相关的检测,请任一合法审查人复制以下内容,在 start merge 前提交评论:

本 pr 不需要兼容性相关检测,对于引发的任何兼容性问题(即由于本 pr 合入将导致用户需适配代码的话),由本人承担。

If you wish to avoid compatibility-related checks, please have any approver copy the following content and submit it as a comment before sending start merge:

This PR does not require compatibility-related checks. For any compatibility issues caused by this PR (i.e., if the integration of this PR will require users to adapt their code), I will take full responsibility.

五、补充说明 📢

likedislike
仓颉编程语言仓颉编程语言管理员
7月17日 添加了label:1.2.0-beta.rc1waiting-start-build
仓颉编程语言仓颉编程语言管理员
7月17日 重置了测试状态
wangyinqiang
wangyinqiang成员
7月17日 评论:

start build

likedislike
此处折叠了275条消息 查看更多
wangyinqiang
wangyinqiang成员
24 天前 评论:

start merge

likedislike
cangjie-ci成员
24 天前 评论:

⏳ 正在进行兼容性检测中,可能需要2~3分钟,请稍候,若10分钟无检测结果,请重新回复 start merge


⏳ Compatibility check in progress. It may take 2–3 minutes. Please wait. If there is no result after 10 minutes, please reply with start merge again.

likedislike
cangjie-ci成员
24 天前 评论:

✅ 合入前兼容性检测通过。
涉及仓库:Cangjie/cangjie_compiler, Cangjie/cangjie_test

结论

  • 分析过程:分析 Cangjie/cangjie_compiler#1934:核对父提交 6a5e48f8 到 PR head 55ee950e 的完整差异,确认仅修改 src/CHIR/AST2CHIR/TranslateASTNode/TranslateAssignExpr.cpp 中复合赋值 VARRAY_GET 的 DebugLocation 传递;进一步检查 CHIR 范围诊断消费路径以及同类 VARRAY_SET/VARRAY_GET 构造方式,未发现公开 .cj API、ABI、跨组件符号、CLI、构建打包或成功编译路径变化。 Analyzed Cangjie/cangjie_compiler#1934 by reviewing the complete parent-to-head diff, the CHIR range-diagnostic consumer, and matching VARRAY_SET/VARRAY_GET construction patterns; no public API, ABI, cross-component symbol, CLI, packaging, or successful-compilation contract changed.
  • 原因:兼容。旧版本在 VArray 复合赋值的越界下标可被静态判定时,会因 VARRAY_GET 缺少源码位置而触发内部编译器错误;新版本仅在 src/CHIR/AST2CHIR/TranslateASTNode/TranslateAssignExpr.cpp:86 将同一赋值表达式的 loc 传入 Intrinsic,供 src/CHIR/Optimization/RangePropagation.cpp:269 生成正常的越界诊断。合法源码的语义、生成代码和接口不变;变化仅把非法程序的 ICE/exit=2 修复为带源码位置的普通编译错误/exit=1,属于错误处理改善,不构成兼容性破坏。 Compatible: the change only attaches the assignment DebugLocation to VARRAY_GET so an out-of-bounds invalid program receives a normal diagnostic instead of an internal compiler error; valid-program semantics, generated code, and exposed contracts remain unchanged.
  • 结论:兼容
likedislike
cangjie-ci成员
24 天前 评论:

✅ 以下PR将同时合入:

✅ The following PRs will be merged simultaneously:

likedislike
Ccangjie-ci维护者
24 天前 合入了pull request,合并节点 SHA:f762730de8aaf74da38c679a3cf6481d06bbc17c