[midend]修复内存泄漏和Heap-buffer-overflow问题(getexternalfunction中及其隐秘的错误),修复全局常量标量访问的错误
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user