From ba21bb320359b30e1ac67f8e2a742b08e78dd0d4 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Thu, 7 Aug 2025 02:53:36 +0800 Subject: [PATCH] =?UTF-8?q?[midend]=E4=BF=AE=E5=A4=8D=E5=86=85=E5=AD=98?= =?UTF-8?q?=E6=B3=84=E6=BC=8F=E5=92=8CHeap-buffer-overflow=E9=97=AE?= =?UTF-8?q?=E9=A2=98(getexternalfunction=E4=B8=AD=E5=8F=8A=E5=85=B6?= =?UTF-8?q?=E9=9A=90=E7=A7=98=E7=9A=84=E9=94=99=E8=AF=AF)=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=85=A8=E5=B1=80=E5=B8=B8=E9=87=8F=E6=A0=87?= =?UTF-8?q?=E9=87=8F=E8=AE=BF=E9=97=AE=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/midend/IR.h | 5 ++++- src/midend/IR.cpp | 26 ++++++++------------------ src/midend/SysYIRGenerator.cpp | 15 +++++++++++---- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/include/midend/IR.h b/src/include/midend/IR.h index bc010c9..d9d618b 100644 --- a/src/include/midend/IR.h +++ b/src/include/midend/IR.h @@ -923,6 +923,9 @@ public: static constexpr uint64_t DefineOpMask = kAlloca | kStore | kPhi; return (kind & DefineOpMask) != 0U; } + + virtual ~Instruction() = default; + virtual void print(std::ostream& os) const = 0; }; // class Instruction @@ -1655,7 +1658,7 @@ class Module { } ///< 获取函数 Function* getExternalFunction(const std::string &name) const { auto result = externalFunctions.find(name); - if (result == functions.end()) { + if (result == externalFunctions.end()) { return nullptr; } return result->second.get(); diff --git a/src/midend/IR.cpp b/src/midend/IR.cpp index 89e44de..0a9cfac 100644 --- a/src/midend/IR.cpp +++ b/src/midend/IR.cpp @@ -1164,17 +1164,20 @@ void Module::cleanup() { } void Function::cleanup() { - // 清理所有基本块中的使用关系 + // 首先清理所有基本块中的使用关系 for (auto& block : blocks) { if (block) { block->cleanup(); } } - // 清理参数列表中的使用关系 + // 然后安全地清理参数列表中的使用关系 for (auto arg : arguments) { if (arg) { + // 清理参数的所有使用关系 arg->cleanup(); + // 现在安全地删除参数对象 + delete arg; } } @@ -1185,14 +1188,7 @@ void Function::cleanup() { } void BasicBlock::cleanup() { - // 清理所有指令中的使用关系 - for (auto& inst : instructions) { - if (inst) { - inst->cleanup(); - } - } - - // 清理指令列表 + // 直接清理指令列表,让析构函数自然处理 instructions.clear(); // 清理前驱后继关系 @@ -1201,14 +1197,8 @@ void BasicBlock::cleanup() { } void User::cleanup() { - // 清理所有操作数的使用关系 - for (auto& operand : operands) { - if (operand && operand->getValue()) { - operand->getValue()->removeUse(operand); - } - } - - // 清理操作数列表 + // 简单清理:让shared_ptr的析构函数自动处理Use关系 + // 这样避免了手动管理可能已经被释放的Value对象 operands.clear(); } diff --git a/src/midend/SysYIRGenerator.cpp b/src/midend/SysYIRGenerator.cpp index fb75465..babf38a 100644 --- a/src/midend/SysYIRGenerator.cpp +++ b/src/midend/SysYIRGenerator.cpp @@ -1658,7 +1658,13 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) { // 这个方法会根据索引深度返回最终的标量值或指向子数组的指针 (作为 ConstantValue/Variable) return constVar->getByIndices(dims); } - // 如果dims为空(数组名单独出现),需要走GEP路径来实现数组到指针的退化 + // 如果dims为空,检查是否是常量标量 + if (dims.empty() && declaredNumDims == 0) { + // 常量标量,直接返回其值 + // 默认传入空索引列表,表示访问标量本身 + return constVar->getByIndices(dims); + } + // 如果dims为空但不是标量(数组名单独出现),需要走GEP路径来实现数组到指针的退化 } // 3. 处理可变变量 (AllocaInst/GlobalValue) 或带非常量索引的常量变量 @@ -1668,7 +1674,8 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) { if (dims.empty() && declaredNumDims == 0) { if (dynamic_cast(variable) || dynamic_cast(variable)) { targetAddress = variable; - } else { + } + else { assert(false && "Unhandled scalar variable type in LValue access."); return static_cast(nullptr); } @@ -1793,10 +1800,10 @@ std::any SysYIRGenerator::visitCall(SysYParser::CallContext *ctx) { // 获取形参列表。`getArguments()` 返回的是 `Argument*` 的集合, // 每个 `Argument` 代表一个函数形参,其 `getType()` 就是指向形参的类型的指针类型。 - auto formalParams = function->getArguments(); + const auto& formalParams = function->getArguments(); // 检查实参和形参数量是否匹配。 - if (args.size() != formalParams.size()) { + if (args.size() != function->getNumArguments()) { std::cerr << "Error: Function call argument count mismatch for function '" << funcName << "'." << std::endl; assert(false && "Function call argument count mismatch!"); }