fix(attr): ALL_CAPS 非 CDefine 回退跨模块全局变量

Phase1.PYI_BUF_SIZE: t.CSizeT = 262144 是 i64 模块级全局而非 CDefine 宏,
语义同 C 的 extern size_t PYI_BUF_SIZE。原 ALL_CAPS 属性路径在 CDefine
查找失败后直接 fail-fast,从不尝试跨模块全局。修复:
- ExprGenAttr 模块限定路径:CDefine 失败时先查 find_global_in_module,
  命中则按跨模块全局引用加载,仅全局也不存在时才 fail-fast;
- ExprGenName 裸名路径:from-import 确认后同样回退跨模块全局加载
  (覆盖 from Phase1 import PYI_BUF_SIZE 形式)。
This commit is contained in:
TermiNexus committed 2026-08-19 05:41:21 +08:00
1 parent aa2a1e593f
commit e8a3fd0a65
2 files changed
+35 -6

No files matched your search

+11 -6
View File
@@ -564,13 +564,18 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
# 此处返回 None,让上层嵌套属性访问路径处理
if string.strcmp(nm_ma.id, "t") == 0 and string.strcmp(at.attr, "ASM_DESCR") == 0:
return None
# CDefine 未找到且属性名符合 ALL_CAPS 约定: fail-fast 终止编译
# 不再创建未定义的外部全局变量引用(否则 llc 报 "use of undefined value")
# ALL_CAPS 模块属性但非 CDefine:先检查模块是否定义了同名全局
# 变量(如 Phase1.PYI_BUF_SIZE: t.CSizeT = 262144 是 i64 全局、
# 非宏,语义同 C 的 extern size_t PYI_BUF_SIZE)→ 按跨模块全局
# 引用加载。仅当全局变量也不存在时才 fail-fast(防 llc
# "use of undefined value")。
if HandlesExpr._is_cdefine_name_pattern(at.attr) != 0:
HandlesType.fatal_error(
at,
f"跨模块 CDefine 未找到: '{nm_ma.id}.{at.attr}'(CDefine cross-module lookup failed)",
"TypeError")
if self.find_global_in_module(mod, at.attr) is None:
HandlesType.fatal_error(
at,
f"跨模块 CDefine 未找到: '{nm_ma.id}.{at.attr}'(CDefine cross-module lookup failed)",
"TypeError")
# 命中跨模块全局 → 落到下方跨模块全局加载路径
# 非 CDefine: 使用 i8* 作为类型提示 (模块级变量通常存储指针)
i8_ptr_hint: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, llvmlite.Int8(pool))
mod_gv_ref: llvmlite.Value | t.CPtr = self._resolve_module_attribute_global(
+24
View File
@@ -99,6 +99,30 @@ class ExprGenName(ExprGenBase.ExprGenBase):
return llvmlite.ConstFloat(pool, llvmlite.Double(pool), dchk_nm)
return HandlesExpr._const_int_for_cdefine(pool, cdef_val)
# CDefine 查找失败:from-import 的模块级全局变量(如
# from Phase1 import PYI_BUF_SIZE;PYI_BUF_SIZE: t.CSizeT = 262144 是
# i64 全局、非宏,语义同 C 的 extern size_t PYI_BUF_SIZE)。from-import
# 确认名称确实来自某模块后,按后缀匹配查找该全局并加载。
if trans is not None and trans._from_imports is not None:
fi_mod_raw: str = HandlesImports.lookup_from_import(
trans._from_imports, nm_id, 0)
if fi_mod_raw is not None:
fi_gv: llvmlite.GlobalVariable | t.CPtr = HandlesExpr.find_global_in_module(
trans.Module, nm_id)
if fi_gv is not None and fi_gv.Ty is not None:
fi_ref: llvmlite.Value | t.CPtr = HandlesExpr.make_global_ref(
pool, nm_id, fi_gv.Ty)
if fi_ref is not None and fi_ref.Ty is not None:
fi_pty: llvmlite.LLVMType | t.CPtr = fi_ref.Ty.Pointee
if fi_pty is not None:
match fi_pty:
case llvmlite.LLVMType.Array(_, _):
# 数组全局按 C 语义退化为基址(对齐 L3383-3388)
return fi_ref
case _:
pass
return llvmlite.build_load(builder, fi_pty, fi_ref)
# global 变量:从模块作用域查找(global 声明优先级最高)
if trans is not None:
if HT.is_global_name(trans, nm_id) != 0: