[midend]修复内存泄漏和Heap-buffer-overflow问题(getexternalfunction中及其隐秘的错误),修复全局常量标量访问的错误

This commit is contained in:
rain2133
2025-08-07 02:53:36 +08:00
parent 8aa5ba692f
commit ba21bb3203
3 changed files with 23 additions and 23 deletions

View File

@@ -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();

View File

@@ -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();
}

View File

@@ -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<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(variable)) {
targetAddress = variable;
} else {
}
else {
assert(false && "Unhandled scalar variable type in LValue access.");
return static_cast<Value*>(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!");
}