mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
add error checks to @Type
This commit is contained in:
parent
4d7013f7d3
commit
9589dc4c95
56
src/ir.cpp
56
src/ir.cpp
@ -2146,6 +2146,7 @@ static IrInstSrc *ir_build_const_undefined(IrBuilderSrc *irb, Scope *scope, AstN
|
||||
IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node);
|
||||
ir_instruction_append(irb->current_basic_block, &const_instruction->base);
|
||||
const_instruction->value = irb->codegen->intern.for_undefined();
|
||||
const_instruction->value->special = ConstValSpecialUndef;
|
||||
return &const_instruction->base;
|
||||
}
|
||||
|
||||
@ -14916,6 +14917,9 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so
|
||||
field_val->parent.data.p_struct.struct_val = const_result->value;
|
||||
field_val->parent.data.p_struct.field_index = dst_field->src_index;
|
||||
field_values[dst_field->src_index] = field_val;
|
||||
if (field_val->type->id == ZigTypeIdUndefined && dst_field->type_entry->id != ZigTypeIdUndefined) {
|
||||
field_values[dst_field->src_index]->special = ConstValSpecialUndef;
|
||||
}
|
||||
} else {
|
||||
is_comptime = false;
|
||||
}
|
||||
@ -15648,7 +15652,7 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
|
||||
wanted_type->data.array.len == field_count)
|
||||
{
|
||||
return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type);
|
||||
} else if (wanted_type->id == ZigTypeIdStruct &&
|
||||
} else if (wanted_type->id == ZigTypeIdStruct && !is_slice(wanted_type) &&
|
||||
(!is_array_init || field_count == 0))
|
||||
{
|
||||
return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type);
|
||||
@ -22301,6 +22305,7 @@ static IrInstGen *ir_analyze_container_member_access_inner(IrAnalyze *ira,
|
||||
|
||||
static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field) {
|
||||
if (field->init_val != nullptr) return;
|
||||
if (field->decl_node == nullptr) return;
|
||||
if (field->decl_node->type != NodeTypeStructField) return;
|
||||
AstNode *init_node = field->decl_node->data.struct_field.value;
|
||||
if (init_node == nullptr) return;
|
||||
@ -26016,6 +26021,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
assert(payload->special == ConstValSpecialStatic);
|
||||
assert(payload->type == type_info_pointer_type);
|
||||
ZigValue *size_value = get_const_field(ira, source_instr->source_node, payload, "size", 0);
|
||||
if (size_value == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
|
||||
assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type));
|
||||
BuiltinPtrSize size_enum_index = (BuiltinPtrSize)bigint_as_u32(&size_value->data.x_enum_tag);
|
||||
PtrLen ptr_len = size_enum_index_to_ptr_len(size_enum_index);
|
||||
@ -26099,13 +26107,21 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
assert(payload->special == ConstValSpecialStatic);
|
||||
assert(payload->type == ir_type_info_get_type(ira, "Optional", nullptr));
|
||||
ZigType *child_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 0);
|
||||
if (type_is_invalid(child_type))
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
return get_optional_type(ira->codegen, child_type);
|
||||
}
|
||||
case ZigTypeIdErrorUnion: {
|
||||
assert(payload->special == ConstValSpecialStatic);
|
||||
assert(payload->type == ir_type_info_get_type(ira, "ErrorUnion", nullptr));
|
||||
ZigType *err_set_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "error_set", 0);
|
||||
if (type_is_invalid(err_set_type))
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
|
||||
ZigType *payload_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "payload", 1);
|
||||
if (type_is_invalid(payload_type))
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
|
||||
return get_error_union_type(ira->codegen, err_set_type, payload_type);
|
||||
}
|
||||
case ZigTypeIdOpaque: {
|
||||
@ -26119,8 +26135,10 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
assert(payload->special == ConstValSpecialStatic);
|
||||
assert(payload->type == ir_type_info_get_type(ira, "Vector", nullptr));
|
||||
BigInt *len = get_const_field_lit_int(ira, source_instr->source_node, payload, "len", 0);
|
||||
if (len == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
|
||||
ZigType *child_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 1);
|
||||
Error err;
|
||||
if ((err = ir_validate_vector_elem_type(ira, source_instr->source_node, child_type))) {
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
}
|
||||
@ -26130,6 +26148,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
assert(payload->special == ConstValSpecialStatic);
|
||||
assert(payload->type == ir_type_info_get_type(ira, "AnyFrame", nullptr));
|
||||
ZigType *child_type = get_const_field_meta_type_optional(ira, source_instr->source_node, payload, "child", 0);
|
||||
if (child_type != nullptr && type_is_invalid(child_type))
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
|
||||
return get_any_frame_type(ira->codegen, child_type);
|
||||
}
|
||||
case ZigTypeIdEnumLiteral:
|
||||
@ -26138,6 +26159,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
assert(payload->special == ConstValSpecialStatic);
|
||||
assert(payload->type == ir_type_info_get_type(ira, "Frame", nullptr));
|
||||
ZigValue *function = get_const_field(ira, source_instr->source_node, payload, "function", 0);
|
||||
if (function == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
|
||||
assert(function->type->id == ZigTypeIdFn);
|
||||
ZigFn *fn = function->data.x_ptr.data.fn.fn_entry;
|
||||
return get_fn_frame_type(ira->codegen, fn);
|
||||
@ -26172,7 +26196,6 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
assert(error->type == ir_type_info_get_type(ira, "Error", nullptr));
|
||||
ErrorTableEntry *err_entry = heap::c_allocator.create<ErrorTableEntry>();
|
||||
err_entry->decl_node = source_instr->source_node;
|
||||
Error err;
|
||||
if ((err = get_const_field_buf(ira, source_instr->source_node, error, "name", 0, &err_entry->name)))
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
auto existing_entry = ira->codegen->error_table.put_unique(&err_entry->name, err_entry);
|
||||
@ -26199,11 +26222,15 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
assert(payload->type == ir_type_info_get_type(ira, "Struct", nullptr));
|
||||
|
||||
ZigValue *layout_value = get_const_field(ira, source_instr->source_node, payload, "layout", 0);
|
||||
if (layout_value == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
assert(layout_value->special == ConstValSpecialStatic);
|
||||
assert(layout_value->type == ir_type_info_get_type(ira, "ContainerLayout", nullptr));
|
||||
ContainerLayout layout = (ContainerLayout)bigint_as_u32(&layout_value->data.x_enum_tag);
|
||||
|
||||
ZigValue *fields_value = get_const_field(ira, source_instr->source_node, payload, "fields", 1);
|
||||
if (fields_value == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
assert(fields_value->special == ConstValSpecialStatic);
|
||||
assert(is_slice(fields_value->type));
|
||||
ZigValue *fields_ptr = fields_value->data.x_struct.fields[slice_ptr_index];
|
||||
@ -26211,6 +26238,8 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
size_t fields_len = bigint_as_usize(&fields_len_value->data.x_bigint);
|
||||
|
||||
ZigValue *decls_value = get_const_field(ira, source_instr->source_node, payload, "decls", 2);
|
||||
if (decls_value == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
assert(decls_value->special == ConstValSpecialStatic);
|
||||
assert(is_slice(decls_value->type));
|
||||
ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index];
|
||||
@ -26221,7 +26250,8 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
}
|
||||
|
||||
bool is_tuple;
|
||||
get_const_field_bool(ira, source_instr->source_node, payload, "is_tuple", 3, &is_tuple);
|
||||
if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_tuple", 3, &is_tuple)))
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
|
||||
ZigType *entry = new_type_table_entry(ZigTypeIdStruct);
|
||||
buf_init_from_buf(&entry->name,
|
||||
@ -26249,6 +26279,8 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
field->decl_node = source_instr->source_node;
|
||||
ZigValue *type_value = get_const_field(ira, source_instr->source_node, field_value, "field_type", 1);
|
||||
if (type_value == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
field->type_val = type_value;
|
||||
field->type_entry = type_value->data.x_type;
|
||||
if (entry->data.structure.fields_by_name.put_unique(field->name, field) != nullptr) {
|
||||
@ -26256,6 +26288,8 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
}
|
||||
ZigValue *default_value = get_const_field(ira, source_instr->source_node, field_value, "default_value", 2);
|
||||
if (default_value == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
if (default_value->type->id == ZigTypeIdNull) {
|
||||
field->init_val = nullptr;
|
||||
} else if (default_value->type->id == ZigTypeIdOptional && default_value->type->data.maybe.child_type == field->type_entry) {
|
||||
@ -26278,6 +26312,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
assert(payload->type == ir_type_info_get_type(ira, "Enum", nullptr));
|
||||
|
||||
ZigValue *layout_value = get_const_field(ira, source_instr->source_node, payload, "layout", 0);
|
||||
if (layout_value == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
|
||||
assert(layout_value->special == ConstValSpecialStatic);
|
||||
assert(layout_value->type == ir_type_info_get_type(ira, "ContainerLayout", nullptr));
|
||||
ContainerLayout layout = (ContainerLayout)bigint_as_u32(&layout_value->data.x_enum_tag);
|
||||
@ -26285,6 +26322,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
ZigType *tag_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "tag_type", 1);
|
||||
|
||||
ZigValue *fields_value = get_const_field(ira, source_instr->source_node, payload, "fields", 2);
|
||||
if (fields_value == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
|
||||
assert(fields_value->special == ConstValSpecialStatic);
|
||||
assert(is_slice(fields_value->type));
|
||||
ZigValue *fields_ptr = fields_value->data.x_struct.fields[slice_ptr_index];
|
||||
@ -26292,6 +26332,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
size_t fields_len = bigint_as_usize(&fields_len_value->data.x_bigint);
|
||||
|
||||
ZigValue *decls_value = get_const_field(ira, source_instr->source_node, payload, "decls", 3);
|
||||
if (decls_value == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
|
||||
assert(decls_value->special == ConstValSpecialStatic);
|
||||
assert(is_slice(decls_value->type));
|
||||
ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index];
|
||||
@ -26337,7 +26380,10 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
|
||||
ir_add_error(ira, source_instr, buf_sprintf("duplicate enum field '%s'", buf_ptr(field->name)));
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
}
|
||||
field->value = *get_const_field_lit_int(ira, source_instr->source_node, field_value, "value", 1);
|
||||
BigInt *field_int_value = get_const_field_lit_int(ira, source_instr->source_node, field_value, "value", 1);
|
||||
if (field_int_value == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
field->value = *field_int_value;
|
||||
}
|
||||
|
||||
return entry;
|
||||
|
@ -2,6 +2,25 @@ const tests = @import("tests.zig");
|
||||
const std = @import("std");
|
||||
|
||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
cases.add("@Type with undefined",
|
||||
\\comptime {
|
||||
\\ _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } });
|
||||
\\}
|
||||
\\comptime {
|
||||
\\ _ = @Type(.{
|
||||
\\ .Struct = .{
|
||||
\\ .fields = undefined,
|
||||
\\ .decls = undefined,
|
||||
\\ .is_tuple = false,
|
||||
\\ .layout = .Auto,
|
||||
\\ },
|
||||
\\ });
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:2:16: error: use of undefined value here causes undefined behavior",
|
||||
"tmp.zig:5:16: error: use of undefined value here causes undefined behavior",
|
||||
});
|
||||
|
||||
cases.add("struct with declarations unavailable for @Type",
|
||||
\\export fn entry() void {
|
||||
\\ _ = @Type(@typeInfo(struct { const foo = 1; }));
|
||||
|
Loading…
Reference in New Issue
Block a user