|
| 1 | +use std::cell::RefCell; |
1 | 2 | use std::sync::Arc; |
2 | 3 |
|
3 | 4 | use super::node_result::NodeResultBuilder; |
4 | 5 | use super::*; |
5 | 6 |
|
6 | 7 | use crate::ast::builder::BuilderEnum; |
7 | 8 | use crate::ast::builder::IRBuilder; |
| 9 | +use crate::ast::builder::IntPredicate; |
8 | 10 | use crate::ast::builder::ValueHandle; |
9 | 11 | use crate::ast::ctx::Ctx; |
10 | 12 | use crate::ast::ctx::MacroReplaceNode; |
@@ -366,6 +368,69 @@ impl Node for ArrayElementNode { |
366 | 368 |
|
367 | 369 | let elemptr: ValueHandle = { |
368 | 370 | let index: &[ValueHandle; 1] = &[index_val]; |
| 371 | + |
| 372 | + // 在debug模式下添加越界检查 |
| 373 | + if ctx.config.assert_index_out_of_bounds { |
| 374 | + // 获取数组大小 |
| 375 | + let size_ptr = builder |
| 376 | + .build_struct_gep(arr, 2, "size_ptr", &pltype.borrow(), ctx) |
| 377 | + .unwrap(); |
| 378 | + let size = builder.build_load( |
| 379 | + size_ptr, |
| 380 | + "arr_size", |
| 381 | + &PLType::Primitive(PriType::I64), |
| 382 | + ctx, |
| 383 | + ); |
| 384 | + |
| 385 | + // 创建比较:index >= size 或 index < 0 |
| 386 | + let cmp_ge = builder.build_int_compare( |
| 387 | + IntPredicate::SGE, |
| 388 | + index_val, |
| 389 | + size, |
| 390 | + "index_ge_size", |
| 391 | + ); |
| 392 | + let cmp_lt = builder.build_int_compare( |
| 393 | + IntPredicate::SLT, |
| 394 | + index_val, |
| 395 | + builder.int_value(&PriType::I64, 0, true), |
| 396 | + "index_lt_zero", |
| 397 | + ); |
| 398 | + let out_of_bounds = builder.build_or(cmp_ge, cmp_lt, "out_of_bounds"); |
| 399 | + |
| 400 | + // 获取当前函数 |
| 401 | + let current_func = ctx.function.unwrap(); |
| 402 | + let error_block = builder.append_basic_block(current_func, "arr_index_error"); |
| 403 | + let continue_block = |
| 404 | + builder.append_basic_block(current_func, "arr_index_continue"); |
| 405 | + |
| 406 | + builder.build_conditional_branch(out_of_bounds, error_block, continue_block); |
| 407 | + |
| 408 | + // 错误处理块 |
| 409 | + builder.position_at_end_block(error_block); |
| 410 | + |
| 411 | + // 获取printf函数 |
| 412 | + let printf_fn = builder |
| 413 | + .get_function("pl_index_out_of_bounds") |
| 414 | + .unwrap_or_else(|| { |
| 415 | + let ret_type = PLType::Void; |
| 416 | + let param_type = PLType::Primitive(PriType::I64); |
| 417 | + builder.add_function( |
| 418 | + "pl_index_out_of_bounds", |
| 419 | + &[param_type.clone(), param_type], |
| 420 | + ret_type, |
| 421 | + ctx, |
| 422 | + ) |
| 423 | + }); |
| 424 | + |
| 425 | + // 调用printf输出错误信息 |
| 426 | + builder.build_call(printf_fn, &[index_val, size], &PLType::Void, ctx, None); |
| 427 | + |
| 428 | + builder.build_unreachable(); |
| 429 | + |
| 430 | + // 继续执行块 |
| 431 | + builder.position_at_end_block(continue_block); |
| 432 | + } |
| 433 | + |
369 | 434 | let real_arr: ValueHandle = builder |
370 | 435 | .build_struct_gep(arr, 1, "real_arr", &pltype.borrow(), ctx) |
371 | 436 | .unwrap(); |
|
0 commit comments