authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-15 21:17:39+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-16 19:53:53+01:00
log096f79260b025ab53d77c4943f237676abb5b7d8
tree448091adf4f32044febeceeec4f694313fbb8811
parentb15958c557d3b29c8d4cee9951a8bfd30c215482

ir: Prevent crash when indexing undefined ptr to array

Closes #4471

2 files changed, 35 insertions(+), 18 deletions(-)

src/ir.cpp+26-18
...@@ -20638,12 +20638,12 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP...@@ -20638,12 +20638,12 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
20638 if (type_is_invalid(array_ptr->value->type))20638 if (type_is_invalid(array_ptr->value->type))
20639 return ira->codegen->invalid_inst_gen;20639 return ira->codegen->invalid_inst_gen;
2064020640
20641 ZigValue *orig_array_ptr_val = array_ptr->value;
20642
20643 IrInstGen *elem_index = elem_ptr_instruction->elem_index->child;20641 IrInstGen *elem_index = elem_ptr_instruction->elem_index->child;
20644 if (type_is_invalid(elem_index->value->type))20642 if (type_is_invalid(elem_index->value->type))
20645 return ira->codegen->invalid_inst_gen;20643 return ira->codegen->invalid_inst_gen;
2064620644
20645 ZigValue *orig_array_ptr_val = array_ptr->value;
20646
20647 ZigType *ptr_type = orig_array_ptr_val->type;20647 ZigType *ptr_type = orig_array_ptr_val->type;
20648 assert(ptr_type->id == ZigTypeIdPointer);20648 assert(ptr_type->id == ZigTypeIdPointer);
2064920649
...@@ -20653,23 +20653,25 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP...@@ -20653,23 +20653,25 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
20653 // We will adjust return_type's alignment before returning it.20653 // We will adjust return_type's alignment before returning it.
20654 ZigType *return_type;20654 ZigType *return_type;
2065520655
20656 if (type_is_invalid(array_type)) {20656 if (type_is_invalid(array_type))
20657 return ira->codegen->invalid_inst_gen;20657 return ira->codegen->invalid_inst_gen;
20658 } else if (array_type->id == ZigTypeIdArray ||20658
20659 (array_type->id == ZigTypeIdPointer &&20659 if (array_type->id == ZigTypeIdPointer &&
20660 array_type->data.pointer.ptr_len == PtrLenSingle &&20660 array_type->data.pointer.ptr_len == PtrLenSingle &&
20661 array_type->data.pointer.child_type->id == ZigTypeIdArray))20661 array_type->data.pointer.child_type->id == ZigTypeIdArray)
20662 {20662 {
20663 if (array_type->id == ZigTypeIdPointer) {20663 IrInstGen *ptr_value = ir_get_deref(ira, &elem_ptr_instruction->base.base,
20664 array_type = array_type->data.pointer.child_type;20664 array_ptr, nullptr);
20665 ptr_type = ptr_type->data.pointer.child_type;20665 if (type_is_invalid(ptr_value->value->type))
20666 if (orig_array_ptr_val->special != ConstValSpecialRuntime) {20666 return ira->codegen->invalid_inst_gen;
20667 orig_array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val,20667
20668 elem_ptr_instruction->base.base.source_node);20668 array_type = array_type->data.pointer.child_type;
20669 if (orig_array_ptr_val == nullptr)20669 ptr_type = ptr_type->data.pointer.child_type;
20670 return ira->codegen->invalid_inst_gen;20670
20671 }20671 orig_array_ptr_val = ptr_value->value;
20672 }20672 }
20673
20674 if (array_type->id == ZigTypeIdArray) {
20673 if (array_type->data.array.len == 0) {20675 if (array_type->data.array.len == 0) {
20674 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node,20676 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node,
20675 buf_sprintf("index 0 outside array of size 0"));20677 buf_sprintf("index 0 outside array of size 0"));
...@@ -20807,8 +20809,14 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP...@@ -20807,8 +20809,14 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
20807 orig_array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&20809 orig_array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
20808 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == ZigTypeIdArray))20810 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == ZigTypeIdArray))
20809 {20811 {
20812 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec,
20813 elem_ptr_instruction->base.base.source_node, orig_array_ptr_val, UndefBad)))
20814 {
20815 return ira->codegen->invalid_inst_gen;
20816 }
20817
20810 ZigValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val,20818 ZigValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val,
20811 elem_ptr_instruction->base.base.source_node);20819 elem_ptr_instruction->base.base.source_node);
20812 if (array_ptr_val == nullptr)20820 if (array_ptr_val == nullptr)
20813 return ira->codegen->invalid_inst_gen;20821 return ira->codegen->invalid_inst_gen;
2081420822
test/compile_errors.zig+9
...@@ -3,6 +3,15 @@ const builtin = @import("builtin");...@@ -3,6 +3,15 @@ const builtin = @import("builtin");
3const Target = @import("std").Target;3const Target = @import("std").Target;
44
5pub fn addCases(cases: *tests.CompileErrorContext) void {5pub fn addCases(cases: *tests.CompileErrorContext) void {
6 cases.addTest("access of undefined pointer to array",
7 \\const ram_u32: *[4096]u32 = undefined;
8 \\export fn entry() void {
9 \\ @ptrCast(*u32, &(ram_u32[0])) = &(ram_u32[0]);
10 \\}
11 , &[_][]const u8{
12 "tmp.zig:3:29: error: use of undefined value here causes undefined behavior",
13 });
14
6 cases.addTest("duplicate field in anonymous struct literal",15 cases.addTest("duplicate field in anonymous struct literal",
7 \\export fn entry() void {16 \\export fn entry() void {
8 \\ const anon = .{17 \\ const anon = .{