authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-11-23 03:02:37+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-12-25 14:58:13+02:00
log0bc82a9070b514bf61fb245f906bf03f8e51ce35
tree92a37866983537e2c3f0834c23a24eb5fd8e4d46
parent990eccf282f278b977f8e232fca5522649eff20f
signaturelock-open Commit is signed but in an unrecognized format.

stage1: validate pointer attributes when coercing anon literals


2 files changed, 40 insertions(+), 15 deletions(-)

src/stage1/ir.cpp+23-15
......@@ -15955,38 +15955,46 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
1595515955 anon_type->data.structure.special == StructSpecialInferredTuple;
1595615956 const uint32_t field_count = anon_type->data.structure.src_field_count;
1595715957
15958 if (wanted_type->id == ZigTypeIdPointer) {
15958 if (wanted_type->id == ZigTypeIdPointer &&
15959 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile))
15960 {
1595915961 ZigType *wanted_child = wanted_type->data.pointer.child_type;
15962 bool const_ok = (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const);
1596015963 if (wanted_child->id == ZigTypeIdArray && (is_array_init || field_count == 0) &&
15961 wanted_child->data.array.len == field_count)
15964 wanted_child->data.array.len == field_count && (const_ok || field_count == 0))
1596215965 {
1596315966 IrInstGen *res = ir_analyze_struct_literal_to_array(ira, source_instr, value, anon_type, wanted_child);
1596415967 if (res->value->type->id == ZigTypeIdPointer)
1596515968 return res;
15966 return ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile);
15969 return ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
1596715970 } else if (wanted_child->id == ZigTypeIdStruct && !is_slice(wanted_type) &&
15968 (!is_array_init || field_count == 0))
15971 (!is_array_init || field_count == 0) && const_ok)
1596915972 {
1597015973 IrInstGen *res = ir_analyze_struct_literal_to_struct(ira, source_instr, value, anon_type, wanted_child);
1597115974 if (res->value->type->id == ZigTypeIdPointer)
1597215975 return res;
15973 return ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile);
15974 } else if (wanted_child->id == ZigTypeIdUnion && !is_array_init && field_count == 1) {
15976 return ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
15977 } else if (wanted_child->id == ZigTypeIdUnion && !is_array_init && field_count == 1 && const_ok) {
1597515978 IrInstGen *res = ir_analyze_struct_literal_to_union(ira, source_instr, value, anon_type, wanted_child);
1597615979 if (res->value->type->id == ZigTypeIdPointer)
1597715980 return res;
15978 return ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile);
15981 return ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
1597915982 }
1598015983 } else if (is_slice(wanted_type) && (is_array_init || field_count == 0)) {
15981 ZigType *slice_child_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type;
15982 ZigType *slice_array_type = get_array_type(ira->codegen, slice_child_type, field_count, nullptr);
15983 IrInstGen *res = ir_analyze_struct_literal_to_array(ira, source_instr, value, anon_type, slice_array_type);
15984 if (type_is_invalid(res->value->type))
15985 return ira->codegen->invalid_inst_gen;
15986 if (res->value->type->id != ZigTypeIdPointer)
15987 res = ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile);
15984 ZigType *slice_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry;
15985 if ((!actual_type->data.pointer.is_const || slice_type->data.pointer.is_const || field_count == 0) &&
15986 (!actual_type->data.pointer.is_volatile || slice_type->data.pointer.is_volatile))
15987 {
15988 ZigType *slice_child_type = slice_type->data.pointer.child_type;
15989 ZigType *slice_array_type = get_array_type(ira->codegen, slice_child_type, field_count, nullptr);
15990 IrInstGen *res = ir_analyze_struct_literal_to_array(ira, source_instr, value, anon_type, slice_array_type);
15991 if (type_is_invalid(res->value->type))
15992 return ira->codegen->invalid_inst_gen;
15993 if (res->value->type->id != ZigTypeIdPointer)
15994 res = ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
1598815995
15989 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, res, wanted_type, nullptr);
15996 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, res, wanted_type, nullptr);
15997 }
1599015998 }
1599115999 }
1599216000
test/compile_errors.zig+17
......@@ -12,6 +12,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1212 "tmp.zig:4:17: error: integer value 1 cannot be coerced to type '*[10]u8'",
1313 });
1414
15 cases.add("pointer attributes checked when coercing pointer to anon literal",
16 \\comptime {
17 \\ const c: [][]const u8 = &.{"hello", "world" };
18 \\}
19 \\comptime {
20 \\ const c: *[2][]const u8 = &.{"hello", "world" };
21 \\}
22 \\const S = struct {a: u8 = 1, b: u32 = 2};
23 \\comptime {
24 \\ const c: *S = &.{};
25 \\}
26 , &[_][]const u8{
27 "mp.zig:2:31: error: expected type '[][]const u8', found '*const struct:2:31'",
28 "mp.zig:5:33: error: expected type '*[2][]const u8', found '*const struct:5:33'",
29 "mp.zig:9:21: error: expected type '*S', found '*const struct:9:21'",
30 });
31
1532 cases.add("@Type() union payload is undefined",
1633 \\const Foo = @Type(@import("std").builtin.TypeInfo{
1734 \\ .Struct = undefined,