authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-05 15:53:36-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-05 15:53:36-04:00
logc87a576cb5afaf54e68bae10119305af71aaa3a1
tree5deeb1a955da7b4e593f6b26703badbc8c3a4b77
parentba7836ea4859b244bf2c7749cc91853ea5512e26
signaturelock-open Commit is signed but in an unrecognized format.

stage1 compile error instead of crashing for unsupported comptime ptr cast

See #955

3 files changed, 280 insertions(+), 139 deletions(-)

doc/langref.html.in+1-1
......@@ -1587,7 +1587,7 @@ test "pointer casting" {
15871587 // operation that Zig cannot protect you against. Use @ptrCast only when other
15881588 // conversions are not possible.
15891589 const bytes align(@alignOf(u32)) = []u8{ 0x12, 0x12, 0x12, 0x12 };
1590 const u32_ptr = @ptrCast(*const u32, &bytes[0]);
1590 const u32_ptr = @ptrCast(*const u32, &bytes);
15911591 assert(u32_ptr.* == 0x12121212);
15921592
15931593 // Even this example is contrived - there are better ways to do the above than
src/ir.cpp+267-138
......@@ -150,8 +150,10 @@ static TypeTableEntry *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruct
150150static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval);
151151static TypeTableEntry *adjust_ptr_align(CodeGen *g, TypeTableEntry *ptr_type, uint32_t new_align);
152152static TypeTableEntry *adjust_slice_align(CodeGen *g, TypeTableEntry *slice_type, uint32_t new_align);
153static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val);
154static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val);
153155
154ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {
156static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
155157 assert(get_codegen_ptr_type(const_val->type) != nullptr);
156158 assert(const_val->special == ConstValSpecialStatic);
157159 ConstExprValue *result;
......@@ -181,6 +183,27 @@ ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {
181183 return result;
182184}
183185
186static bool types_have_same_zig_comptime_repr(TypeTableEntry *a, TypeTableEntry *b) {
187 if (a == b)
188 return true;
189
190 if (a->id == b->id)
191 return true;
192
193 if (get_codegen_ptr_type(a) != nullptr && get_codegen_ptr_type(b) != nullptr)
194 return true;
195
196 return false;
197}
198
199ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {
200 ConstExprValue *result = const_ptr_pointee_unchecked(g, const_val);
201 if (const_val->type->id == TypeTableEntryIdPointer) {
202 assert(types_have_same_zig_comptime_repr(const_val->type->data.pointer.child_type, result->type));
203 }
204 return result;
205}
206
184207static bool ir_should_inline(IrExecutable *exec, Scope *scope) {
185208 if (exec->is_inline)
186209 return true;
......@@ -7602,6 +7625,19 @@ static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction,
76027625 return ir_add_error_node(ira, source_instruction->source_node, msg);
76037626}
76047627
7628static ConstExprValue *ir_const_ptr_pointee(IrAnalyze *ira, ConstExprValue *const_val, AstNode *source_node) {
7629 ConstExprValue *val = const_ptr_pointee_unchecked(ira->codegen, const_val);
7630 assert(val != nullptr);
7631 assert(const_val->type->id == TypeTableEntryIdPointer);
7632 TypeTableEntry *expected_type = const_val->type->data.pointer.child_type;
7633 if (!types_have_same_zig_comptime_repr(val->type, expected_type)) {
7634 ir_add_error_node(ira, source_node,
7635 buf_sprintf("TODO handle comptime reinterpreted pointer. See https://github.com/ziglang/zig/issues/955"));
7636 return nullptr;
7637 }
7638 return val;
7639}
7640
76057641static IrInstruction *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec) {
76067642 IrBasicBlock *bb = exec->basic_block_list.at(0);
76077643 for (size_t i = 0; i < bb->instruction_list.length; i += 1) {
......@@ -9461,7 +9497,9 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira,
94619497 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, value->value.type->data.pointer.alignment);
94629498
94639499 if (instr_is_comptime(value)) {
9464 ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value);
9500 ConstExprValue *pointee = ir_const_ptr_pointee(ira, &value->value, source_instr->source_node);
9501 if (pointee == nullptr)
9502 return ira->codegen->invalid_instruction;
94659503 if (pointee->special != ConstValSpecialRuntime) {
94669504 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
94679505 source_instr->source_node, wanted_type);
......@@ -9487,7 +9525,9 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
94879525 wanted_type = adjust_slice_align(ira->codegen, wanted_type, value->value.type->data.pointer.alignment);
94889526
94899527 if (instr_is_comptime(value)) {
9490 ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value);
9528 ConstExprValue *pointee = ir_const_ptr_pointee(ira, &value->value, source_instr->source_node);
9529 if (pointee == nullptr)
9530 return ira->codegen->invalid_instruction;
94919531 if (pointee->special != ConstValSpecialRuntime) {
94929532 assert(value->value.type->id == TypeTableEntryIdPointer);
94939533 TypeTableEntry *array_type = value->value.type->data.pointer.child_type;
......@@ -10458,7 +10498,9 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou
1045810498 return ira->codegen->invalid_instruction;
1045910499
1046010500 assert(val->type->id == TypeTableEntryIdPointer);
10461 ConstExprValue *pointee = const_ptr_pointee(ira->codegen, val);
10501 ConstExprValue *pointee = ir_const_ptr_pointee(ira, val, source_instr->source_node);
10502 if (pointee == nullptr)
10503 return ira->codegen->invalid_instruction;
1046210504 if (pointee->special != ConstValSpecialRuntime) {
1046310505 ConstExprValue *array_val = create_const_vals(1);
1046410506 array_val->special = ConstValSpecialStatic;
......@@ -10773,6 +10815,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1077310815 !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk)
1077410816 {
1077510817 IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_child_type);
10818 if (type_is_invalid(cast1->value.type))
10819 return ira->codegen->invalid_instruction;
1077610820 return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type);
1077710821 }
1077810822 }
......@@ -11045,7 +11089,9 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
1104511089 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst ||
1104611090 ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar)
1104711091 {
11048 ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &ptr->value);
11092 ConstExprValue *pointee = ir_const_ptr_pointee(ira, &ptr->value, source_instruction->source_node);
11093 if (pointee == nullptr)
11094 return ira->codegen->invalid_instruction;
1104911095 if (pointee->special != ConstValSpecialRuntime) {
1105011096 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope,
1105111097 source_instruction->source_node, child_type);
......@@ -13716,7 +13762,39 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
1371613762 }
1371713763}
1371813764
13765// out_val->type must be the type to read the pointer as
13766// if the type is different than the actual type then it does a comptime byte reinterpretation
13767static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node,
13768 ConstExprValue *out_val, ConstExprValue *ptr_val)
13769{
13770 assert(out_val->type != nullptr);
13771
13772 ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, ptr_val);
13773
13774 size_t src_size = type_size(ira->codegen, pointee->type);
13775 size_t dst_size = type_size(ira->codegen, out_val->type);
13776
13777 if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) {
13778 copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst);
13779 return ErrorNone;
13780 }
13781
13782 if (dst_size > src_size) {
13783 ir_add_error_node(ira, source_node,
13784 buf_sprintf("attempt to read %zu bytes from pointer to %s which is %zu bytes",
13785 dst_size, buf_ptr(&pointee->type->name), src_size));
13786 return ErrorSemanticAnalyzeFail;
13787 }
13788
13789 Buf buf = BUF_INIT;
13790 buf_resize(&buf, src_size);
13791 buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), pointee);
13792 buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val);
13793 return ErrorNone;
13794}
13795
1371913796static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
13797 Error err;
1372013798 IrInstruction *value = un_op_instruction->value->other;
1372113799
1372213800 TypeTableEntry *ptr_type = value->value.type;
......@@ -13746,12 +13824,11 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp
1374613824 if (comptime_value == nullptr)
1374713825 return ira->codegen->builtin_types.entry_invalid;
1374813826
13749 ConstExprValue *pointee = const_ptr_pointee(ira->codegen, comptime_value);
13750 if (pointee->type == child_type) {
13751 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);
13752 copy_const_val(out_val, pointee, value->value.data.x_ptr.mut == ConstPtrMutComptimeConst);
13753 return child_type;
13754 }
13827 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);
13828 out_val->type = child_type;
13829 if ((err = ir_read_const_ptr(ira, un_op_instruction->base.source_node, out_val, comptime_value)))
13830 return ira->codegen->builtin_types.entry_invalid;
13831 return child_type;
1375513832 }
1375613833
1375713834 ir_build_load_ptr_from(&ira->new_irb, &un_op_instruction->base, value);
......@@ -14152,7 +14229,10 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
1415214229 array_type = array_type->data.pointer.child_type;
1415314230 ptr_type = ptr_type->data.pointer.child_type;
1415414231 if (orig_array_ptr_val->special != ConstValSpecialRuntime) {
14155 orig_array_ptr_val = const_ptr_pointee(ira->codegen, orig_array_ptr_val);
14232 orig_array_ptr_val = ir_const_ptr_pointee(ira, orig_array_ptr_val,
14233 elem_ptr_instruction->base.source_node);
14234 if (orig_array_ptr_val == nullptr)
14235 return ira->codegen->builtin_types.entry_invalid;
1415614236 }
1415714237 }
1415814238 if (array_type->data.array.len == 0) {
......@@ -14193,7 +14273,9 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
1419314273 ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);
1419414274 if (!ptr_val)
1419514275 return ira->codegen->builtin_types.entry_invalid;
14196 ConstExprValue *args_val = const_ptr_pointee(ira->codegen, ptr_val);
14276 ConstExprValue *args_val = ir_const_ptr_pointee(ira, ptr_val, elem_ptr_instruction->base.source_node);
14277 if (args_val == nullptr)
14278 return ira->codegen->builtin_types.entry_invalid;
1419714279 size_t start = args_val->data.x_arg_tuple.start_index;
1419814280 size_t end = args_val->data.x_arg_tuple.end_index;
1419914281 uint64_t elem_index_val;
......@@ -14269,120 +14351,126 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
1426914351 return_type = adjust_ptr_align(ira->codegen, return_type, chosen_align);
1427014352 }
1427114353
14272 ConstExprValue *array_ptr_val;
1427314354 if (orig_array_ptr_val->special != ConstValSpecialRuntime &&
14274 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == TypeTableEntryIdArray) &&
14275 (array_ptr_val = const_ptr_pointee(ira->codegen, orig_array_ptr_val)) &&
14276 array_ptr_val->special != ConstValSpecialRuntime &&
14277 (array_type->id != TypeTableEntryIdPointer ||
14278 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr))
14355 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar ||
14356 array_type->id == TypeTableEntryIdArray))
1427914357 {
14280 if (array_type->id == TypeTableEntryIdPointer) {
14281 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base);
14282 out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut;
14283 size_t new_index;
14284 size_t mem_size;
14285 size_t old_size;
14286 switch (array_ptr_val->data.x_ptr.special) {
14287 case ConstPtrSpecialInvalid:
14288 case ConstPtrSpecialDiscard:
14289 zig_unreachable();
14290 case ConstPtrSpecialRef:
14291 mem_size = 1;
14292 old_size = 1;
14293 new_index = index;
14294
14295 out_val->data.x_ptr.special = ConstPtrSpecialRef;
14296 out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee;
14297 break;
14298 case ConstPtrSpecialBaseArray:
14299 {
14300 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index;
14301 new_index = offset + index;
14302 mem_size = array_ptr_val->data.x_ptr.data.base_array.array_val->type->data.array.len;
14303 old_size = mem_size - offset;
14304
14305 assert(array_ptr_val->data.x_ptr.data.base_array.array_val);
14306
14307 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
14308 out_val->data.x_ptr.data.base_array.array_val =
14309 array_ptr_val->data.x_ptr.data.base_array.array_val;
14310 out_val->data.x_ptr.data.base_array.elem_index = new_index;
14311 out_val->data.x_ptr.data.base_array.is_cstr =
14312 array_ptr_val->data.x_ptr.data.base_array.is_cstr;
14358 ConstExprValue *array_ptr_val = ir_const_ptr_pointee(ira, orig_array_ptr_val,
14359 elem_ptr_instruction->base.source_node);
14360 if (array_ptr_val == nullptr)
14361 return ira->codegen->builtin_types.entry_invalid;
1431314362
14363 if (array_ptr_val->special != ConstValSpecialRuntime &&
14364 (array_type->id != TypeTableEntryIdPointer ||
14365 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr))
14366 {
14367 if (array_type->id == TypeTableEntryIdPointer) {
14368 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base);
14369 out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut;
14370 size_t new_index;
14371 size_t mem_size;
14372 size_t old_size;
14373 switch (array_ptr_val->data.x_ptr.special) {
14374 case ConstPtrSpecialInvalid:
14375 case ConstPtrSpecialDiscard:
14376 zig_unreachable();
14377 case ConstPtrSpecialRef:
14378 mem_size = 1;
14379 old_size = 1;
14380 new_index = index;
14381
14382 out_val->data.x_ptr.special = ConstPtrSpecialRef;
14383 out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee;
1431414384 break;
14315 }
14316 case ConstPtrSpecialBaseStruct:
14317 zig_panic("TODO elem ptr on a const inner struct");
14318 case ConstPtrSpecialHardCodedAddr:
14319 zig_unreachable();
14320 case ConstPtrSpecialFunction:
14321 zig_panic("TODO element ptr of a function casted to a ptr");
14322 }
14323 if (new_index >= mem_size) {
14324 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
14325 buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size));
14326 return ira->codegen->builtin_types.entry_invalid;
14327 }
14328 return return_type;
14329 } else if (is_slice(array_type)) {
14330 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];
14331 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
14332 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node,
14333 array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len);
14334 result->value.type = return_type;
14335 ir_link_new_instruction(result, &elem_ptr_instruction->base);
14385 case ConstPtrSpecialBaseArray:
14386 {
14387 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index;
14388 new_index = offset + index;
14389 mem_size = array_ptr_val->data.x_ptr.data.base_array.array_val->type->data.array.len;
14390 old_size = mem_size - offset;
14391
14392 assert(array_ptr_val->data.x_ptr.data.base_array.array_val);
14393
14394 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
14395 out_val->data.x_ptr.data.base_array.array_val =
14396 array_ptr_val->data.x_ptr.data.base_array.array_val;
14397 out_val->data.x_ptr.data.base_array.elem_index = new_index;
14398 out_val->data.x_ptr.data.base_array.is_cstr =
14399 array_ptr_val->data.x_ptr.data.base_array.is_cstr;
14400
14401 break;
14402 }
14403 case ConstPtrSpecialBaseStruct:
14404 zig_panic("TODO elem ptr on a const inner struct");
14405 case ConstPtrSpecialHardCodedAddr:
14406 zig_unreachable();
14407 case ConstPtrSpecialFunction:
14408 zig_panic("TODO element ptr of a function casted to a ptr");
14409 }
14410 if (new_index >= mem_size) {
14411 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
14412 buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size));
14413 return ira->codegen->builtin_types.entry_invalid;
14414 }
1433614415 return return_type;
14337 }
14338 ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index];
14339 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base);
14340 uint64_t slice_len = bigint_as_unsigned(&len_field->data.x_bigint);
14341 if (index >= slice_len) {
14342 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
14343 buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64,
14344 index, slice_len));
14345 return ira->codegen->builtin_types.entry_invalid;
14346 }
14347 out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut;
14348 switch (ptr_field->data.x_ptr.special) {
14349 case ConstPtrSpecialInvalid:
14350 case ConstPtrSpecialDiscard:
14351 zig_unreachable();
14352 case ConstPtrSpecialRef:
14353 out_val->data.x_ptr.special = ConstPtrSpecialRef;
14354 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee;
14355 break;
14356 case ConstPtrSpecialBaseArray:
14357 {
14358 size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index;
14359 uint64_t new_index = offset + index;
14360 assert(new_index < ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len);
14361 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
14362 out_val->data.x_ptr.data.base_array.array_val =
14363 ptr_field->data.x_ptr.data.base_array.array_val;
14364 out_val->data.x_ptr.data.base_array.elem_index = new_index;
14365 out_val->data.x_ptr.data.base_array.is_cstr =
14366 ptr_field->data.x_ptr.data.base_array.is_cstr;
14416 } else if (is_slice(array_type)) {
14417 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];
14418 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
14419 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node,
14420 array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len);
14421 result->value.type = return_type;
14422 ir_link_new_instruction(result, &elem_ptr_instruction->base);
14423 return return_type;
14424 }
14425 ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index];
14426 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base);
14427 uint64_t slice_len = bigint_as_unsigned(&len_field->data.x_bigint);
14428 if (index >= slice_len) {
14429 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
14430 buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64,
14431 index, slice_len));
14432 return ira->codegen->builtin_types.entry_invalid;
14433 }
14434 out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut;
14435 switch (ptr_field->data.x_ptr.special) {
14436 case ConstPtrSpecialInvalid:
14437 case ConstPtrSpecialDiscard:
14438 zig_unreachable();
14439 case ConstPtrSpecialRef:
14440 out_val->data.x_ptr.special = ConstPtrSpecialRef;
14441 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee;
1436714442 break;
14368 }
14369 case ConstPtrSpecialBaseStruct:
14370 zig_panic("TODO elem ptr on a slice backed by const inner struct");
14371 case ConstPtrSpecialHardCodedAddr:
14372 zig_unreachable();
14373 case ConstPtrSpecialFunction:
14374 zig_panic("TODO elem ptr on a slice that was ptrcast from a function");
14443 case ConstPtrSpecialBaseArray:
14444 {
14445 size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index;
14446 uint64_t new_index = offset + index;
14447 assert(new_index < ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len);
14448 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
14449 out_val->data.x_ptr.data.base_array.array_val =
14450 ptr_field->data.x_ptr.data.base_array.array_val;
14451 out_val->data.x_ptr.data.base_array.elem_index = new_index;
14452 out_val->data.x_ptr.data.base_array.is_cstr =
14453 ptr_field->data.x_ptr.data.base_array.is_cstr;
14454 break;
14455 }
14456 case ConstPtrSpecialBaseStruct:
14457 zig_panic("TODO elem ptr on a slice backed by const inner struct");
14458 case ConstPtrSpecialHardCodedAddr:
14459 zig_unreachable();
14460 case ConstPtrSpecialFunction:
14461 zig_panic("TODO elem ptr on a slice that was ptrcast from a function");
14462 }
14463 return return_type;
14464 } else if (array_type->id == TypeTableEntryIdArray) {
14465 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base);
14466 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
14467 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut;
14468 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val;
14469 out_val->data.x_ptr.data.base_array.elem_index = index;
14470 return return_type;
14471 } else {
14472 zig_unreachable();
1437514473 }
14376 return return_type;
14377 } else if (array_type->id == TypeTableEntryIdArray) {
14378 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base);
14379 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
14380 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut;
14381 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val;
14382 out_val->data.x_ptr.data.base_array.elem_index = index;
14383 return return_type;
14384 } else {
14385 zig_unreachable();
1438614474 }
1438714475 }
1438814476
......@@ -14474,7 +14562,9 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
1447414562 return ira->codegen->invalid_instruction;
1447514563
1447614564 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
14477 ConstExprValue *struct_val = const_ptr_pointee(ira->codegen, ptr_val);
14565 ConstExprValue *struct_val = ir_const_ptr_pointee(ira, ptr_val, source_instr->source_node);
14566 if (struct_val == nullptr)
14567 return ira->codegen->invalid_instruction;
1447814568 if (type_is_invalid(struct_val->type))
1447914569 return ira->codegen->invalid_instruction;
1448014570 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];
......@@ -14516,7 +14606,9 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
1451614606 return ira->codegen->invalid_instruction;
1451714607
1451814608 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
14519 ConstExprValue *union_val = const_ptr_pointee(ira->codegen, ptr_val);
14609 ConstExprValue *union_val = ir_const_ptr_pointee(ira, ptr_val, source_instr->source_node);
14610 if (union_val == nullptr)
14611 return ira->codegen->invalid_instruction;
1452014612 if (type_is_invalid(union_val->type))
1452114613 return ira->codegen->invalid_instruction;
1452214614
......@@ -14711,7 +14803,9 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
1471114803 return ira->codegen->builtin_types.entry_invalid;
1471214804
1471314805 assert(container_ptr->value.type->id == TypeTableEntryIdPointer);
14714 ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val);
14806 ConstExprValue *child_val = ir_const_ptr_pointee(ira, container_ptr_val, source_node);
14807 if (child_val == nullptr)
14808 return ira->codegen->builtin_types.entry_invalid;
1471514809
1471614810 if (buf_eql_str(field_name, "len")) {
1471714811 ConstExprValue *len_val = create_const_vals(1);
......@@ -14735,7 +14829,9 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
1473514829 return ira->codegen->builtin_types.entry_invalid;
1473614830
1473714831 assert(container_ptr->value.type->id == TypeTableEntryIdPointer);
14738 ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val);
14832 ConstExprValue *child_val = ir_const_ptr_pointee(ira, container_ptr_val, source_node);
14833 if (child_val == nullptr)
14834 return ira->codegen->builtin_types.entry_invalid;
1473914835 TypeTableEntry *child_type = child_val->data.x_type;
1474014836
1474114837 if (type_is_invalid(child_type)) {
......@@ -15003,7 +15099,10 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
1500315099 if (!container_ptr_val)
1500415100 return ira->codegen->builtin_types.entry_invalid;
1500515101
15006 ConstExprValue *namespace_val = const_ptr_pointee(ira->codegen, container_ptr_val);
15102 ConstExprValue *namespace_val = ir_const_ptr_pointee(ira, container_ptr_val,
15103 field_ptr_instruction->base.source_node);
15104 if (namespace_val == nullptr)
15105 return ira->codegen->builtin_types.entry_invalid;
1500715106 assert(namespace_val->special == ConstValSpecialStatic);
1500815107
1500915108 ImportTableEntry *namespace_import = namespace_val->data.x_import;
......@@ -15079,7 +15178,9 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru
1507915178 }
1508015179 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) {
1508115180 if (instr_is_comptime(casted_value)) {
15082 ConstExprValue *dest_val = const_ptr_pointee(ira->codegen, &ptr->value);
15181 ConstExprValue *dest_val = ir_const_ptr_pointee(ira, &ptr->value, store_ptr_instruction->base.source_node);
15182 if (dest_val == nullptr)
15183 return ira->codegen->builtin_types.entry_invalid;
1508315184 if (dest_val->special != ConstValSpecialRuntime) {
1508415185 *dest_val = casted_value->value;
1508515186 if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) {
......@@ -15090,7 +15191,7 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru
1509015191 }
1509115192 ir_add_error(ira, &store_ptr_instruction->base,
1509215193 buf_sprintf("cannot store runtime value in compile time variable"));
15093 ConstExprValue *dest_val = const_ptr_pointee(ira->codegen, &ptr->value);
15194 ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value);
1509415195 dest_val->type = ira->codegen->builtin_types.entry_invalid;
1509515196
1509615197 return ira->codegen->builtin_types.entry_invalid;
......@@ -15656,7 +15757,9 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira,
1565615757 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
1565715758 if (!val)
1565815759 return ira->codegen->builtin_types.entry_invalid;
15659 ConstExprValue *maybe_val = const_ptr_pointee(ira->codegen, val);
15760 ConstExprValue *maybe_val = ir_const_ptr_pointee(ira, val, unwrap_maybe_instruction->base.source_node);
15761 if (maybe_val == nullptr)
15762 return ira->codegen->builtin_types.entry_invalid;
1566015763
1566115764 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
1566215765 if (optional_value_is_null(maybe_val)) {
......@@ -15947,7 +16050,10 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1594716050 TypeTableEntry *target_type = target_value_ptr->value.type->data.pointer.child_type;
1594816051 ConstExprValue *pointee_val = nullptr;
1594916052 if (instr_is_comptime(target_value_ptr)) {
15950 pointee_val = const_ptr_pointee(ira->codegen, &target_value_ptr->value);
16053 pointee_val = ir_const_ptr_pointee(ira, &target_value_ptr->value, target_value_ptr->source_node);
16054 if (pointee_val == nullptr)
16055 return ira->codegen->builtin_types.entry_invalid;
16056
1595116057 if (pointee_val->special == ConstValSpecialRuntime)
1595216058 pointee_val = nullptr;
1595316059 }
......@@ -16078,7 +16184,10 @@ static TypeTableEntry *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstr
1607816184 if (!target_value_ptr)
1607916185 return ira->codegen->builtin_types.entry_invalid;
1608016186
16081 ConstExprValue *pointee_val = const_ptr_pointee(ira->codegen, target_val_ptr);
16187 ConstExprValue *pointee_val = ir_const_ptr_pointee(ira, target_val_ptr, instruction->base.source_node);
16188 if (pointee_val == nullptr)
16189 return ira->codegen->builtin_types.entry_invalid;
16190
1608216191 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
1608316192 out_val->data.x_ptr.special = ConstPtrSpecialRef;
1608416193 out_val->data.x_ptr.mut = target_val_ptr->data.x_ptr.mut;
......@@ -18815,19 +18924,30 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
1881518924 if (array_type->id == TypeTableEntryIdPointer) {
1881618925 TypeTableEntry *child_array_type = array_type->data.pointer.child_type;
1881718926 assert(child_array_type->id == TypeTableEntryIdArray);
18818 parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
18819 array_val = const_ptr_pointee(ira->codegen, parent_ptr);
18927 parent_ptr = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node);
18928 if (parent_ptr == nullptr)
18929 return ira->codegen->builtin_types.entry_invalid;
18930
18931 array_val = ir_const_ptr_pointee(ira, parent_ptr, instruction->base.source_node);
18932 if (array_val == nullptr)
18933 return ira->codegen->builtin_types.entry_invalid;
18934
1882018935 rel_end = child_array_type->data.array.len;
1882118936 abs_offset = 0;
1882218937 } else {
18823 array_val = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
18938 array_val = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node);
18939 if (array_val == nullptr)
18940 return ira->codegen->builtin_types.entry_invalid;
1882418941 rel_end = array_type->data.array.len;
1882518942 parent_ptr = nullptr;
1882618943 abs_offset = 0;
1882718944 }
1882818945 } else if (array_type->id == TypeTableEntryIdPointer) {
1882918946 assert(array_type->data.pointer.ptr_len == PtrLenUnknown);
18830 parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
18947 parent_ptr = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node);
18948 if (parent_ptr == nullptr)
18949 return ira->codegen->builtin_types.entry_invalid;
18950
1883118951 if (parent_ptr->special == ConstValSpecialUndef) {
1883218952 array_val = nullptr;
1883318953 abs_offset = 0;
......@@ -18858,7 +18978,10 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
1885818978 zig_panic("TODO slice of ptr cast from function");
1885918979 }
1886018980 } else if (is_slice(array_type)) {
18861 ConstExprValue *slice_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
18981 ConstExprValue *slice_ptr = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node);
18982 if (slice_ptr == nullptr)
18983 return ira->codegen->builtin_types.entry_invalid;
18984
1886218985 parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index];
1886318986 ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index];
1886418987
......@@ -19258,7 +19381,9 @@ static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInst
1925819381 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
1925919382 BigInt *op1_bigint = &casted_op1->value.data.x_bigint;
1926019383 BigInt *op2_bigint = &casted_op2->value.data.x_bigint;
19261 ConstExprValue *pointee_val = const_ptr_pointee(ira->codegen, &casted_result_ptr->value);
19384 ConstExprValue *pointee_val = ir_const_ptr_pointee(ira, &casted_result_ptr->value, casted_result_ptr->source_node);
19385 if (pointee_val == nullptr)
19386 return ira->codegen->builtin_types.entry_invalid;
1926219387 BigInt *dest_bigint = &pointee_val->data.x_bigint;
1926319388 switch (instruction->op) {
1926419389 case IrOverflowOpAdd:
......@@ -19358,7 +19483,9 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira,
1935819483 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);
1935919484 if (!ptr_val)
1936019485 return ira->codegen->builtin_types.entry_invalid;
19361 ConstExprValue *err_union_val = const_ptr_pointee(ira->codegen, ptr_val);
19486 ConstExprValue *err_union_val = ir_const_ptr_pointee(ira, ptr_val, instruction->base.source_node);
19487 if (err_union_val == nullptr)
19488 return ira->codegen->builtin_types.entry_invalid;
1936219489 if (err_union_val->special != ConstValSpecialRuntime) {
1936319490 ErrorTableEntry *err = err_union_val->data.x_err_union.err;
1936419491 assert(err);
......@@ -19406,7 +19533,9 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
1940619533 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);
1940719534 if (!ptr_val)
1940819535 return ira->codegen->builtin_types.entry_invalid;
19409 ConstExprValue *err_union_val = const_ptr_pointee(ira->codegen, ptr_val);
19536 ConstExprValue *err_union_val = ir_const_ptr_pointee(ira, ptr_val, instruction->base.source_node);
19537 if (err_union_val == nullptr)
19538 return ira->codegen->builtin_types.entry_invalid;
1941019539 if (err_union_val->special != ConstValSpecialRuntime) {
1941119540 ErrorTableEntry *err = err_union_val->data.x_err_union.err;
1941219541 if (err != nullptr) {
test/compile_errors.zig+12
......@@ -1,6 +1,18 @@
11const tests = @import("tests.zig");
22
33pub fn addCases(cases: *tests.CompileErrorContext) void {
4 cases.add(
5 "load too many bytes from comptime reinterpreted pointer",
6 \\export fn entry() void {
7 \\ const float: f32 = 5.99999999999994648725e-01;
8 \\ const float_ptr = &float;
9 \\ const int_ptr = @ptrCast(*const i64, float_ptr);
10 \\ const int_val = int_ptr.*;
11 \\}
12 ,
13 ".tmp_source.zig:5:28: error: attempt to read 8 bytes from pointer to f32 which is 4 bytes",
14 );
15
416 cases.add(
517 "invalid type used in array type",
618 \\const Item = struct {