[midend]修复内存泄漏和Heap-buffer-overflow问题(getexternalfunction中及其隐秘的错误),修复全局常量标量访问的错误
This commit is contained in:
@@ -923,6 +923,9 @@ public:
|
|||||||
static constexpr uint64_t DefineOpMask = kAlloca | kStore | kPhi;
|
static constexpr uint64_t DefineOpMask = kAlloca | kStore | kPhi;
|
||||||
return (kind & DefineOpMask) != 0U;
|
return (kind & DefineOpMask) != 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual ~Instruction() = default;
|
||||||
|
|
||||||
virtual void print(std::ostream& os) const = 0;
|
virtual void print(std::ostream& os) const = 0;
|
||||||
}; // class Instruction
|
}; // class Instruction
|
||||||
|
|
||||||
@@ -1655,7 +1658,7 @@ class Module {
|
|||||||
} ///< 获取函数
|
} ///< 获取函数
|
||||||
Function* getExternalFunction(const std::string &name) const {
|
Function* getExternalFunction(const std::string &name) const {
|
||||||
auto result = externalFunctions.find(name);
|
auto result = externalFunctions.find(name);
|
||||||
if (result == functions.end()) {
|
if (result == externalFunctions.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return result->second.get();
|
return result->second.get();
|
||||||
|
|||||||
@@ -1164,17 +1164,20 @@ void Module::cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Function::cleanup() {
|
void Function::cleanup() {
|
||||||
// 清理所有基本块中的使用关系
|
// 首先清理所有基本块中的使用关系
|
||||||
for (auto& block : blocks) {
|
for (auto& block : blocks) {
|
||||||
if (block) {
|
if (block) {
|
||||||
block->cleanup();
|
block->cleanup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清理参数列表中的使用关系
|
// 然后安全地清理参数列表中的使用关系
|
||||||
for (auto arg : arguments) {
|
for (auto arg : arguments) {
|
||||||
if (arg) {
|
if (arg) {
|
||||||
|
// 清理参数的所有使用关系
|
||||||
arg->cleanup();
|
arg->cleanup();
|
||||||
|
// 现在安全地删除参数对象
|
||||||
|
delete arg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1185,14 +1188,7 @@ void Function::cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BasicBlock::cleanup() {
|
void BasicBlock::cleanup() {
|
||||||
// 清理所有指令中的使用关系
|
// 直接清理指令列表,让析构函数自然处理
|
||||||
for (auto& inst : instructions) {
|
|
||||||
if (inst) {
|
|
||||||
inst->cleanup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清理指令列表
|
|
||||||
instructions.clear();
|
instructions.clear();
|
||||||
|
|
||||||
// 清理前驱后继关系
|
// 清理前驱后继关系
|
||||||
@@ -1201,14 +1197,8 @@ void BasicBlock::cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void User::cleanup() {
|
void User::cleanup() {
|
||||||
// 清理所有操作数的使用关系
|
// 简单清理:让shared_ptr的析构函数自动处理Use关系
|
||||||
for (auto& operand : operands) {
|
// 这样避免了手动管理可能已经被释放的Value对象
|
||||||
if (operand && operand->getValue()) {
|
|
||||||
operand->getValue()->removeUse(operand);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清理操作数列表
|
|
||||||
operands.clear();
|
operands.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1658,7 +1658,13 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) {
|
|||||||
// 这个方法会根据索引深度返回最终的标量值或指向子数组的指针 (作为 ConstantValue/Variable)
|
// 这个方法会根据索引深度返回最终的标量值或指向子数组的指针 (作为 ConstantValue/Variable)
|
||||||
return constVar->getByIndices(dims);
|
return constVar->getByIndices(dims);
|
||||||
}
|
}
|
||||||
// 如果dims为空(数组名单独出现),需要走GEP路径来实现数组到指针的退化
|
// 如果dims为空,检查是否是常量标量
|
||||||
|
if (dims.empty() && declaredNumDims == 0) {
|
||||||
|
// 常量标量,直接返回其值
|
||||||
|
// 默认传入空索引列表,表示访问标量本身
|
||||||
|
return constVar->getByIndices(dims);
|
||||||
|
}
|
||||||
|
// 如果dims为空但不是标量(数组名单独出现),需要走GEP路径来实现数组到指针的退化
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 处理可变变量 (AllocaInst/GlobalValue) 或带非常量索引的常量变量
|
// 3. 处理可变变量 (AllocaInst/GlobalValue) 或带非常量索引的常量变量
|
||||||
@@ -1668,7 +1674,8 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) {
|
|||||||
if (dims.empty() && declaredNumDims == 0) {
|
if (dims.empty() && declaredNumDims == 0) {
|
||||||
if (dynamic_cast<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(variable)) {
|
if (dynamic_cast<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(variable)) {
|
||||||
targetAddress = variable;
|
targetAddress = variable;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
assert(false && "Unhandled scalar variable type in LValue access.");
|
assert(false && "Unhandled scalar variable type in LValue access.");
|
||||||
return static_cast<Value*>(nullptr);
|
return static_cast<Value*>(nullptr);
|
||||||
}
|
}
|
||||||
@@ -1793,10 +1800,10 @@ std::any SysYIRGenerator::visitCall(SysYParser::CallContext *ctx) {
|
|||||||
|
|
||||||
// 获取形参列表。`getArguments()` 返回的是 `Argument*` 的集合,
|
// 获取形参列表。`getArguments()` 返回的是 `Argument*` 的集合,
|
||||||
// 每个 `Argument` 代表一个函数形参,其 `getType()` 就是指向形参的类型的指针类型。
|
// 每个 `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;
|
std::cerr << "Error: Function call argument count mismatch for function '" << funcName << "'." << std::endl;
|
||||||
assert(false && "Function call argument count mismatch!");
|
assert(false && "Function call argument count mismatch!");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user