authorgravatar for matthew.mcallister.0@gmail.comMatthew McAllister <matthew.mcallister.0@gmail.com> 2019-02-02 13:57:53-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-02 22:22:00-05:00
logc90c256868a80cd35e9ba679ba082330592620c9
tree0e7dfa879c8e55dc8d2babf482730cab79d717de
parent9b8e23934bc87f1fd6a42cdfdd551212994b6e58

Fix slice concatenation

This was causing an underflow error

2 files changed, 14 insertions(+), 23 deletions(-)

src/ir.cpp+12-21
...@@ -12369,7 +12369,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i...@@ -12369,7 +12369,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
12369 op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val;12369 op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val;
12370 op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;12370 op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;
12371 ConstExprValue *len_val = &op1_val->data.x_struct.fields[slice_len_index];12371 ConstExprValue *len_val = &op1_val->data.x_struct.fields[slice_len_index];
12372 op1_array_end = bigint_as_unsigned(&len_val->data.x_bigint);12372 op1_array_end = op1_array_index + bigint_as_unsigned(&len_val->data.x_bigint);
12373 } else {12373 } else {
12374 ir_add_error(ira, op1,12374 ir_add_error(ira, op1,
12375 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op1->value.type->name)));12375 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op1->value.type->name)));
...@@ -12379,13 +12379,9 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i...@@ -12379,13 +12379,9 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
12379 ConstExprValue *op2_array_val;12379 ConstExprValue *op2_array_val;
12380 size_t op2_array_index;12380 size_t op2_array_index;
12381 size_t op2_array_end;12381 size_t op2_array_end;
12382 bool op2_type_valid;
12382 if (op2_type->id == ZigTypeIdArray) {12383 if (op2_type->id == ZigTypeIdArray) {
12383 if (op2_type->data.array.child_type != child_type) {12384 op2_type_valid = op2_type->data.array.child_type == child_type;
12384 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'",
12385 buf_ptr(&child_type->name),
12386 buf_ptr(&op2->value.type->name)));
12387 return ira->codegen->invalid_instruction;
12388 }
12389 op2_array_val = op2_val;12385 op2_array_val = op2_val;
12390 op2_array_index = 0;12386 op2_array_index = 0;
12391 op2_array_end = op2_array_val->type->data.array.len;12387 op2_array_end = op2_array_val->type->data.array.len;
...@@ -12394,35 +12390,30 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i...@@ -12394,35 +12390,30 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
12394 op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray &&12390 op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray &&
12395 op2_val->data.x_ptr.data.base_array.is_cstr)12391 op2_val->data.x_ptr.data.base_array.is_cstr)
12396 {12392 {
12397 if (child_type != ira->codegen->builtin_types.entry_u8) {12393 op2_type_valid = child_type == ira->codegen->builtin_types.entry_u8;
12398 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'",
12399 buf_ptr(&child_type->name),
12400 buf_ptr(&op2->value.type->name)));
12401 return ira->codegen->invalid_instruction;
12402 }
12403 op2_array_val = op2_val->data.x_ptr.data.base_array.array_val;12394 op2_array_val = op2_val->data.x_ptr.data.base_array.array_val;
12404 op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index;12395 op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index;
12405 op2_array_end = op2_array_val->type->data.array.len - 1;12396 op2_array_end = op2_array_val->type->data.array.len - 1;
12406 } else if (is_slice(op2_type)) {12397 } else if (is_slice(op2_type)) {
12407 ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry;12398 ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry;
12408 if (ptr_type->data.pointer.child_type != child_type) {12399 op2_type_valid = ptr_type->data.pointer.child_type == child_type;
12409 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'",
12410 buf_ptr(&child_type->name),
12411 buf_ptr(&op2->value.type->name)));
12412 return ira->codegen->invalid_instruction;
12413 }
12414 ConstExprValue *ptr_val = &op2_val->data.x_struct.fields[slice_ptr_index];12400 ConstExprValue *ptr_val = &op2_val->data.x_struct.fields[slice_ptr_index];
12415 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);12401 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);
12416 op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val;12402 op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val;
12417 op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;12403 op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;
12418 op2_array_end = op2_array_val->type->data.array.len;
12419 ConstExprValue *len_val = &op2_val->data.x_struct.fields[slice_len_index];12404 ConstExprValue *len_val = &op2_val->data.x_struct.fields[slice_len_index];
12420 op2_array_end = bigint_as_unsigned(&len_val->data.x_bigint);12405 op2_array_end = op2_array_index + bigint_as_unsigned(&len_val->data.x_bigint);
12421 } else {12406 } else {
12422 ir_add_error(ira, op2,12407 ir_add_error(ira, op2,
12423 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name)));12408 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name)));
12424 return ira->codegen->invalid_instruction;12409 return ira->codegen->invalid_instruction;
12425 }12410 }
12411 if (!op2_type_valid) {
12412 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'",
12413 buf_ptr(&child_type->name),
12414 buf_ptr(&op2->value.type->name)));
12415 return ira->codegen->invalid_instruction;
12416 }
1242612417
12427 // The type of result is populated in the following if blocks12418 // The type of result is populated in the following if blocks
12428 IrInstruction *result = ir_const(ira, &instruction->base, nullptr);12419 IrInstruction *result = ir_const(ira, &instruction->base, nullptr);
test/stage1/behavior/eval.zig+2-2
...@@ -728,8 +728,8 @@ test "comptime pointer cast array and then slice" {...@@ -728,8 +728,8 @@ test "comptime pointer cast array and then slice" {
728728
729test "slice bounds in comptime concatenation" {729test "slice bounds in comptime concatenation" {
730 const bs = comptime blk: {730 const bs = comptime blk: {
731 const b = c"11";731 const b = c"........1........";
732 break :blk b[0..1];732 break :blk b[8..9];
733 };733 };
734 const str = "" ++ bs;734 const str = "" ++ bs;
735 assertOrPanic(str.len == 1);735 assertOrPanic(str.len == 1);