authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-18 14:34:30-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-18 14:34:30-04:00
log5fd3af9dc6ef08f23e6b64dfa6d6776371f9344a
treeae86c5cefa78386e0470deb89856f61f4c78bf2b
parent1fc2019031ef427e02acc88d7ce1c15372556c4d
signaturelock-open Commit is signed but in an unrecognized format.

fix implicit cast of packed struct field to const ptr

closes #966

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

src/ir.cpp+18-14
......@@ -10015,21 +10015,25 @@ static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_
1001510015
1001610016 if (value->id == IrInstructionIdLoadPtr) {
1001710017 IrInstructionLoadPtr *load_ptr_inst = (IrInstructionLoadPtr *)value;
10018 return load_ptr_inst->ptr;
10019 } else {
10020 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instr->scope,
10021 source_instr->source_node, value, true, false);
10022 new_instruction->value.type = wanted_type;
10018 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type,
10019 load_ptr_inst->ptr->value.type, source_instr->source_node, false);
10020 if (const_cast_result.id == ConstCastResultIdInvalid)
10021 return ira->codegen->invalid_instruction;
10022 if (const_cast_result.id == ConstCastResultIdOk)
10023 return load_ptr_inst->ptr;
10024 }
10025 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instr->scope,
10026 source_instr->source_node, value, true, false);
10027 new_instruction->value.type = wanted_type;
1002310028
10024 ZigType *child_type = wanted_type->data.pointer.child_type;
10025 if (type_has_bits(child_type)) {
10026 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
10027 assert(fn_entry);
10028 fn_entry->alloca_list.append(new_instruction);
10029 }
10030 ir_add_alloca(ira, new_instruction, child_type);
10031 return new_instruction;
10029 ZigType *child_type = wanted_type->data.pointer.child_type;
10030 if (type_has_bits(child_type)) {
10031 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
10032 assert(fn_entry);
10033 fn_entry->alloca_list.append(new_instruction);
1003210034 }
10035 ir_add_alloca(ira, new_instruction, child_type);
10036 return new_instruction;
1003310037}
1003410038
1003510039static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) {
......@@ -11057,7 +11061,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1105711061 }
1105811062 }
1105911063
11060 // enum to &const union which has the enum as the tag type
11064 // enum to *const union which has the enum as the tag type
1106111065 if (actual_type->id == ZigTypeIdEnum && wanted_type->id == ZigTypeIdPointer) {
1106211066 ZigType *union_type = wanted_type->data.pointer.child_type;
1106311067 if (union_type->data.unionation.decl_node->data.container_decl.auto_enum ||
test/cases/struct.zig+16
......@@ -437,3 +437,19 @@ test "call method with mutable reference to struct with no fields" {
437437 assert(S.do(&s));
438438 assert(s.do());
439439}
440
441test "implicit cast packed struct field to const ptr" {
442 const LevelUpMove = packed struct {
443 move_id: u9,
444 level: u7,
445
446 fn toInt(value: *const u7) u7 {
447 return value.*;
448 }
449 };
450
451 var lup: LevelUpMove = undefined;
452 lup.level = 12;
453 const res = LevelUpMove.toInt(lup.level);
454 assert(res == 12);
455}