Commit d9f0446b1f
Changed files (5)
src/all_types.hpp
@@ -308,6 +308,7 @@ struct ConstGlobalRefs {
enum LazyValueId {
LazyValueIdInvalid,
LazyValueIdAlignOf,
+ LazyValueIdSizeOf,
LazyValueIdPtrType,
LazyValueIdOptType,
LazyValueIdSliceType,
@@ -326,6 +327,13 @@ struct LazyValueAlignOf {
IrInstruction *target_type;
};
+struct LazyValueSizeOf {
+ LazyValue base;
+
+ IrAnalyze *ira;
+ IrInstruction *target_type;
+};
+
struct LazyValueSliceType {
LazyValue base;
src/analyze.cpp
@@ -997,6 +997,7 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi
switch (type_val->data.x_lazy->id) {
case LazyValueIdInvalid:
case LazyValueIdAlignOf:
+ case LazyValueIdSizeOf:
zig_unreachable();
case LazyValueIdPtrType: {
LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
@@ -1036,6 +1037,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool
switch (type_val->data.x_lazy->id) {
case LazyValueIdInvalid:
case LazyValueIdAlignOf:
+ case LazyValueIdSizeOf:
zig_unreachable();
case LazyValueIdSliceType:
case LazyValueIdPtrType:
@@ -1055,6 +1057,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue
switch (type_val->data.x_lazy->id) {
case LazyValueIdInvalid:
case LazyValueIdAlignOf:
+ case LazyValueIdSizeOf:
zig_unreachable();
case LazyValueIdSliceType: {
LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
@@ -1105,7 +1108,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue
zig_unreachable();
}
-static Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ConstExprValue *type_val,
+Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ConstExprValue *type_val,
size_t *abi_size, size_t *size_in_bits)
{
Error err;
@@ -1123,12 +1126,42 @@ start_over:
switch (type_val->data.x_lazy->id) {
case LazyValueIdInvalid:
case LazyValueIdAlignOf:
+ case LazyValueIdSizeOf:
zig_unreachable();
- case LazyValueIdSliceType:
- *abi_size = g->builtin_types.entry_usize->abi_size * 2;
- *size_in_bits = g->builtin_types.entry_usize->size_in_bits * 2;
+ case LazyValueIdSliceType: {
+ LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
+ bool is_zero_bits;
+ if ((err = type_val_resolve_zero_bits(g, &lazy_slice_type->elem_type->value, nullptr,
+ nullptr, &is_zero_bits)))
+ {
+ return err;
+ }
+ if (is_zero_bits) {
+ *abi_size = g->builtin_types.entry_usize->abi_size;
+ *size_in_bits = g->builtin_types.entry_usize->size_in_bits;
+ } else {
+ *abi_size = g->builtin_types.entry_usize->abi_size * 2;
+ *size_in_bits = g->builtin_types.entry_usize->size_in_bits * 2;
+ }
return ErrorNone;
- case LazyValueIdPtrType:
+ }
+ case LazyValueIdPtrType: {
+ LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
+ bool is_zero_bits;
+ if ((err = type_val_resolve_zero_bits(g, &lazy_ptr_type->elem_type->value, nullptr,
+ nullptr, &is_zero_bits)))
+ {
+ return err;
+ }
+ if (is_zero_bits) {
+ *abi_size = 0;
+ *size_in_bits = 0;
+ } else {
+ *abi_size = g->builtin_types.entry_usize->abi_size;
+ *size_in_bits = g->builtin_types.entry_usize->size_in_bits;
+ }
+ return ErrorNone;
+ }
case LazyValueIdFnType:
*abi_size = g->builtin_types.entry_usize->abi_size;
*size_in_bits = g->builtin_types.entry_usize->size_in_bits;
@@ -1159,6 +1192,7 @@ Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t
switch (type_val->data.x_lazy->id) {
case LazyValueIdInvalid:
case LazyValueIdAlignOf:
+ case LazyValueIdSizeOf:
zig_unreachable();
case LazyValueIdSliceType:
case LazyValueIdPtrType:
@@ -1193,6 +1227,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, Cons
switch (type_val->data.x_lazy->id) {
case LazyValueIdInvalid:
case LazyValueIdAlignOf:
+ case LazyValueIdSizeOf:
zig_unreachable();
case LazyValueIdSliceType: // it has the len field
case LazyValueIdOptType: // it has the optional bit
@@ -4202,7 +4237,12 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {
return;
}
}
- assert(callee->anal_state == FnAnalStateComplete);
+ if (callee->anal_state != FnAnalStateComplete) {
+ add_node_error(g, call->base.source_node,
+ buf_sprintf("call to function '%s' depends on itself", buf_ptr(&callee->symbol_name)));
+ fn->anal_state = FnAnalStateInvalid;
+ return;
+ }
analyze_fn_async(g, callee, true);
if (callee->anal_state == FnAnalStateInvalid) {
fn->anal_state = FnAnalStateInvalid;
@@ -4480,6 +4520,8 @@ void semantic_analyze(CodeGen *g) {
ZigFn *fn = g->fn_defs.at(g->fn_defs_index);
g->trace_err = nullptr;
analyze_fn_async(g, fn, true);
+ if (fn->anal_state == FnAnalStateInvalid)
+ continue;
if (fn_is_async(fn) && fn->non_async_node != nullptr) {
ErrorMsg *msg = add_node_error(g, fn->proto_node,
buf_sprintf("'%s' cannot be async", buf_ptr(&fn->symbol_name)));
@@ -5632,6 +5674,11 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
return ErrorSemanticAnalyzeFail;
}
analyze_fn_async(g, callee, true);
+ if (callee->inferred_async_node == inferred_async_checking) {
+ assert(g->errors.length != 0);
+ frame_type->data.frame.locals_struct = g->builtin_types.entry_invalid;
+ return ErrorSemanticAnalyzeFail;
+ }
if (!fn_is_async(callee))
continue;
src/analyze.hpp
@@ -247,6 +247,8 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
bool fn_is_async(ZigFn *fn);
Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align);
+Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ConstExprValue *type_val,
+ size_t *abi_size, size_t *size_in_bits);
ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field);
ZigType *resolve_struct_field_type(CodeGen *g, TypeStructField *struct_field);
src/codegen.cpp
@@ -6845,6 +6845,7 @@ static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) {
}
static void do_code_gen(CodeGen *g) {
+ Error err;
assert(!g->errors.length);
generate_error_name_table(g);
@@ -6858,6 +6859,8 @@ static void do_code_gen(CodeGen *g) {
// Generate debug info for it but that's it.
ConstExprValue *const_val = var->const_value;
assert(const_val->special != ConstValSpecialRuntime);
+ if ((err = ir_resolve_lazy(g, var->decl_node, const_val)))
+ zig_unreachable();
if (const_val->type != var->var_type) {
zig_panic("TODO debug info for var with ptr casted value");
}
@@ -6875,6 +6878,8 @@ static void do_code_gen(CodeGen *g) {
// Generate debug info for it but that's it.
ConstExprValue *const_val = var->const_value;
assert(const_val->special != ConstValSpecialRuntime);
+ if ((err = ir_resolve_lazy(g, var->decl_node, const_val)))
+ zig_unreachable();
if (const_val->type != var->var_type) {
zig_panic("TODO debug info for var with ptr casted value");
}
src/ir.cpp
@@ -18066,54 +18066,20 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,
zig_unreachable();
}
-static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
- IrInstructionSizeOf *size_of_instruction)
-{
- Error err;
- IrInstruction *type_value = size_of_instruction->type_value->child;
- ZigType *type_entry = ir_resolve_type(ira, type_value);
+static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstructionSizeOf *instruction) {
+ IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int);
+ result->value.special = ConstValSpecialLazy;
- if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown)))
+ LazyValueSizeOf *lazy_size_of = allocate<LazyValueSizeOf>(1);
+ lazy_size_of->ira = ira;
+ result->value.data.x_lazy = &lazy_size_of->base;
+ lazy_size_of->base.id = LazyValueIdSizeOf;
+
+ lazy_size_of->target_type = instruction->type_value->child;
+ if (ir_resolve_type_lazy(ira, lazy_size_of->target_type) == nullptr)
return ira->codegen->invalid_instruction;
- switch (type_entry->id) {
- case ZigTypeIdInvalid: // handled above
- zig_unreachable();
- case ZigTypeIdUnreachable:
- case ZigTypeIdUndefined:
- case ZigTypeIdNull:
- case ZigTypeIdBoundFn:
- case ZigTypeIdArgTuple:
- case ZigTypeIdOpaque:
- ir_add_error_node(ira, type_value->source_node,
- buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name)));
- return ira->codegen->invalid_instruction;
- case ZigTypeIdMetaType:
- case ZigTypeIdEnumLiteral:
- case ZigTypeIdComptimeFloat:
- case ZigTypeIdComptimeInt:
- case ZigTypeIdVoid:
- case ZigTypeIdBool:
- case ZigTypeIdInt:
- case ZigTypeIdFloat:
- case ZigTypeIdPointer:
- case ZigTypeIdArray:
- case ZigTypeIdStruct:
- case ZigTypeIdOptional:
- case ZigTypeIdErrorUnion:
- case ZigTypeIdErrorSet:
- case ZigTypeIdEnum:
- case ZigTypeIdUnion:
- case ZigTypeIdFn:
- case ZigTypeIdVector:
- case ZigTypeIdFnFrame:
- case ZigTypeIdAnyFrame:
- {
- uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
- return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes);
- }
- }
- zig_unreachable();
+ return result;
}
static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) {
@@ -25548,6 +25514,61 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) {
bigint_init_unsigned(&val->data.x_bigint, align_in_bytes);
return ErrorNone;
}
+ case LazyValueIdSizeOf: {
+ LazyValueSizeOf *lazy_size_of = reinterpret_cast<LazyValueSizeOf *>(val->data.x_lazy);
+ IrAnalyze *ira = lazy_size_of->ira;
+
+ if (lazy_size_of->target_type->value.special == ConstValSpecialStatic) {
+ switch (lazy_size_of->target_type->value.data.x_type->id) {
+ case ZigTypeIdInvalid: // handled above
+ zig_unreachable();
+ case ZigTypeIdUnreachable:
+ case ZigTypeIdUndefined:
+ case ZigTypeIdNull:
+ case ZigTypeIdBoundFn:
+ case ZigTypeIdArgTuple:
+ case ZigTypeIdOpaque:
+ ir_add_error(ira, lazy_size_of->target_type,
+ buf_sprintf("no size available for type '%s'",
+ buf_ptr(&lazy_size_of->target_type->value.data.x_type->name)));
+ return ErrorSemanticAnalyzeFail;
+ case ZigTypeIdMetaType:
+ case ZigTypeIdEnumLiteral:
+ case ZigTypeIdComptimeFloat:
+ case ZigTypeIdComptimeInt:
+ case ZigTypeIdVoid:
+ case ZigTypeIdBool:
+ case ZigTypeIdInt:
+ case ZigTypeIdFloat:
+ case ZigTypeIdPointer:
+ case ZigTypeIdArray:
+ case ZigTypeIdStruct:
+ case ZigTypeIdOptional:
+ case ZigTypeIdErrorUnion:
+ case ZigTypeIdErrorSet:
+ case ZigTypeIdEnum:
+ case ZigTypeIdUnion:
+ case ZigTypeIdFn:
+ case ZigTypeIdVector:
+ case ZigTypeIdFnFrame:
+ case ZigTypeIdAnyFrame:
+ break;
+ }
+ }
+
+ uint64_t abi_size;
+ uint64_t size_in_bits;
+ if ((err = type_val_resolve_abi_size(ira->codegen, source_node, &lazy_size_of->target_type->value,
+ &abi_size, &size_in_bits)))
+ {
+ return err;
+ }
+
+ val->special = ConstValSpecialStatic;
+ assert(val->type->id == ZigTypeIdComptimeInt);
+ bigint_init_unsigned(&val->data.x_bigint, abi_size);
+ return ErrorNone;
+ }
case LazyValueIdSliceType: {
LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy);
IrAnalyze *ira = lazy_slice_type->ira;