diff --git a/src/analyze.cpp b/src/analyze.cpp index c9b45164f2..336ea55a69 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -597,7 +597,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con entry->size_in_bits = SIZE_MAX; entry->abi_align = UINT32_MAX; } else if (type_is_resolved(child_type, ResolveStatusZeroBitsKnown)) { - if (type_has_bits(child_type)) { + if (type_has_bits(g, child_type)) { entry->abi_size = g->builtin_types.entry_usize->abi_size; entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits; entry->abi_align = g->builtin_types.entry_usize->abi_align; @@ -660,11 +660,11 @@ ZigType *get_optional_type(CodeGen *g, ZigType *child_type) { buf_resize(&entry->name, 0); buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name)); - if (!type_has_bits(child_type)) { + if (!type_has_bits(g, child_type)) { entry->size_in_bits = g->builtin_types.entry_bool->size_in_bits; entry->abi_size = g->builtin_types.entry_bool->abi_size; entry->abi_align = g->builtin_types.entry_bool->abi_align; - } else if (type_is_nonnull_ptr(child_type) || child_type->id == ZigTypeIdErrorSet) { + } else if (type_is_nonnull_ptr(g, child_type) || child_type->id == ZigTypeIdErrorSet) { // This is an optimization but also is necessary for calling C // functions where all pointers are optional pointers. // Function types are technically pointers. @@ -729,8 +729,8 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa entry->data.error_union.err_set_type = err_set_type; entry->data.error_union.payload_type = payload_type; - if (!type_has_bits(payload_type)) { - if (type_has_bits(err_set_type)) { + if (!type_has_bits(g, payload_type)) { + if (type_has_bits(g, err_set_type)) { entry->size_in_bits = err_set_type->size_in_bits; entry->abi_size = err_set_type->abi_size; entry->abi_align = err_set_type->abi_align; @@ -739,7 +739,7 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa entry->abi_size = 0; entry->abi_align = 0; } - } else if (!type_has_bits(err_set_type)) { + } else if (!type_has_bits(g, err_set_type)) { entry->size_in_bits = payload_type->size_in_bits; entry->abi_size = payload_type->abi_size; entry->abi_align = payload_type->abi_align; @@ -856,13 +856,13 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) { entry->data.structure.requires_comptime = true; } - if (!type_has_bits(ptr_type)) { + if (!type_has_bits(g, ptr_type)) { entry->data.structure.gen_field_count = 1; entry->data.structure.fields[slice_ptr_index]->gen_index = SIZE_MAX; entry->data.structure.fields[slice_len_index]->gen_index = 0; } - if (type_has_bits(ptr_type)) { + if (type_has_bits(g, ptr_type)) { entry->size_in_bits = ptr_type->size_in_bits + g->builtin_types.entry_usize->size_in_bits; entry->abi_size = ptr_type->abi_size + g->builtin_types.entry_usize->abi_size; entry->abi_align = ptr_type->abi_align; @@ -969,12 +969,12 @@ ZigType *get_stack_trace_type(CodeGen *g) { bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) { if (fn_type_id->cc == CallingConventionUnspecified) { - return handle_is_ptr(fn_type_id->return_type); + return handle_is_ptr(g, fn_type_id->return_type); } if (fn_type_id->cc != CallingConventionC) { return false; } - if (type_is_c_abi_int(g, fn_type_id->return_type)) { + if (type_is_c_abi_int_bail(g, fn_type_id->return_type)) { return false; } if (g->zig_target->arch == ZigLLVM_x86 || @@ -1650,15 +1650,16 @@ static Error emit_error_unless_type_allowed_in_packed_container(CodeGen *g, ZigT return ErrorSemanticAnalyzeFail; } zig_unreachable(); - case ZigTypeIdOptional: - if (get_codegen_ptr_type(type_entry) != nullptr) { - return ErrorNone; - } else { - add_node_error(g, source_node, - buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation", - buf_ptr(&type_entry->name), container_name)); - return ErrorSemanticAnalyzeFail; - } + case ZigTypeIdOptional: { + ZigType *ptr_type; + if ((err = get_codegen_ptr_type(g, type_entry, &ptr_type))) return err; + if (ptr_type != nullptr) return ErrorNone; + + add_node_error(g, source_node, + buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation", + buf_ptr(&type_entry->name), container_name)); + return ErrorSemanticAnalyzeFail; + } case ZigTypeIdEnum: { AstNode *decl_node = type_entry->data.enumeration.decl_node; if (decl_node->data.container_decl.init_arg_expr != nullptr) { @@ -1737,7 +1738,7 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) { case ZigTypeIdPointer: if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown))) return err; - if (!type_has_bits(type_entry)) { + if (!type_has_bits(g, type_entry)) { *result = false; return ErrorNone; } @@ -1753,7 +1754,7 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) { *result = false; return ErrorNone; } - if (!type_is_nonnull_ptr(child_type)) { + if (!type_is_nonnull_ptr(g, child_type)) { *result = false; return ErrorNone; } @@ -1848,7 +1849,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc if (!calling_convention_allows_zig_types(fn_type_id.cc)) { if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown))) return g->builtin_types.entry_invalid; - if (!type_has_bits(type_entry)) { + if (!type_has_bits(g, type_entry)) { add_node_error(g, param_node->data.param_decl.type, buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", buf_ptr(&type_entry->name), calling_convention_name(fn_type_id.cc))); @@ -2082,7 +2083,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel field->src_index = i; field->align = fields[i].align; - if (type_has_bits(field->type_entry)) { + if (type_has_bits(g, field->type_entry)) { assert(type_is_resolved(field->type_entry, ResolveStatusSizeKnown)); unsigned field_abi_align = max(field->align, field->type_entry->abi_align); if (field_abi_align > abi_align) { @@ -2097,7 +2098,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel size_t next_offset = 0; for (size_t i = 0; i < field_count; i += 1) { TypeStructField *field = struct_type->data.structure.fields[i]; - if (!type_has_bits(field->type_entry)) + if (!type_has_bits(g, field->type_entry)) continue; field->offset = next_offset; @@ -2105,7 +2106,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel // find the next non-zero-byte field for offset calculations size_t next_src_field_index = i + 1; for (; next_src_field_index < field_count; next_src_field_index += 1) { - if (type_has_bits(struct_type->data.structure.fields[next_src_field_index]->type_entry)) + if (type_has_bits(g, struct_type->data.structure.fields[next_src_field_index]->type_entry)) break; } size_t next_abi_align; @@ -2402,7 +2403,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { union_type->data.unionation.most_aligned_union_member = most_aligned_union_member; ZigType *tag_type = union_type->data.unionation.tag_type; - if (tag_type != nullptr && type_has_bits(tag_type)) { + if (tag_type != nullptr && type_has_bits(g, tag_type)) { if ((err = type_resolve(g, tag_type, ResolveStatusAlignmentKnown))) { union_type->data.unionation.resolve_status = ResolveStatusInvalid; return ErrorSemanticAnalyzeFail; @@ -2504,7 +2505,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { if (type_is_invalid(union_type)) return ErrorSemanticAnalyzeFail; - if (!type_has_bits(field_type)) + if (!type_has_bits(g, field_type)) continue; union_abi_size = max(union_abi_size, field_type->abi_size); @@ -2523,7 +2524,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { union_type->data.unionation.union_abi_size = union_abi_size; ZigType *tag_type = union_type->data.unionation.tag_type; - if (tag_type != nullptr && type_has_bits(tag_type)) { + if (tag_type != nullptr && type_has_bits(g, tag_type)) { if ((err = type_resolve(g, tag_type, ResolveStatusSizeKnown))) { union_type->data.unionation.resolve_status = ResolveStatusInvalid; return ErrorSemanticAnalyzeFail; @@ -2998,7 +2999,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { } } - if (!type_has_bits(struct_type)) { + if (!type_has_bits(g, struct_type)) { assert(struct_type->abi_align == 0); } @@ -4416,15 +4417,50 @@ ZigType *get_src_ptr_type(ZigType *type) { return nullptr; } -ZigType *get_codegen_ptr_type(ZigType *type) { +Error get_codegen_ptr_type(CodeGen *g, ZigType *type, ZigType **result) { + Error err; + ZigType *ty = get_src_ptr_type(type); - if (ty == nullptr || !type_has_bits(ty)) - return nullptr; - return ty; + if (ty == nullptr) { + *result = nullptr; + return ErrorNone; + } + + bool has_bits; + if ((err = type_has_bits2(g, ty, &has_bits))) return err; + if (!has_bits) { + *result = nullptr; + return ErrorNone; + } + + *result = ty; + return ErrorNone; } -bool type_is_nonnull_ptr(ZigType *type) { - return get_codegen_ptr_type(type) == type && !ptr_allows_addr_zero(type); +ZigType *get_codegen_ptr_type_bail(CodeGen *g, ZigType *type) { + Error err; + ZigType *result; + if ((err = get_codegen_ptr_type(g, type, &result))) { + codegen_report_errors_and_exit(g); + } + return result; +} + +bool type_is_nonnull_ptr(CodeGen *g, ZigType *type) { + Error err; + bool result; + if ((err = type_is_nonnull_ptr2(g, type, &result))) { + codegen_report_errors_and_exit(g); + } + return result; +} + +Error type_is_nonnull_ptr2(CodeGen *g, ZigType *type, bool *result) { + Error err; + ZigType *ptr_type; + if ((err = get_codegen_ptr_type(g, type, &ptr_type))) return err; + *result = ptr_type == type && !ptr_allows_addr_zero(type); + return ErrorNone; } static uint32_t get_async_frame_align_bytes(CodeGen *g) { @@ -4499,8 +4535,12 @@ static Error define_local_param_variables(CodeGen *g, ZigFn *fn_table_entry) { } bool is_noalias = param_info->is_noalias; - if (is_noalias && get_codegen_ptr_type(param_type) == nullptr) { - add_node_error(g, param_decl_node, buf_sprintf("noalias on non-pointer parameter")); + if (is_noalias) { + ZigType *ptr_type; + if ((err = get_codegen_ptr_type(g, param_type, &ptr_type))) return err; + if (ptr_type == nullptr) { + add_node_error(g, param_decl_node, buf_sprintf("noalias on non-pointer parameter")); + } } ZigVar *var = add_variable(g, param_decl_node, fn_table_entry->child_scope, @@ -4509,7 +4549,7 @@ static Error define_local_param_variables(CodeGen *g, ZigFn *fn_table_entry) { fn_table_entry->child_scope = var->child_scope; var->shadowable = var->shadowable || is_var_args; - if (type_has_bits(param_type)) { + if (type_has_bits(g, param_type)) { fn_table_entry->variable_list.append(var); } } @@ -5027,15 +5067,35 @@ ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) { return new_entry; } -bool is_valid_vector_elem_type(ZigType *elem_type) { - return elem_type->id == ZigTypeIdInt || +Error is_valid_vector_elem_type(CodeGen *g, ZigType *elem_type, bool *result) { + if (elem_type->id == ZigTypeIdInt || elem_type->id == ZigTypeIdFloat || - elem_type->id == ZigTypeIdBool || - get_codegen_ptr_type(elem_type) != nullptr; + elem_type->id == ZigTypeIdBool) + { + *result = true; + return ErrorNone; + } + + Error err; + ZigType *ptr_type; + if ((err = get_codegen_ptr_type(g, elem_type, &ptr_type))) return err; + if (ptr_type != nullptr) { + *result = true; + return ErrorNone; + } + + *result = false; + return ErrorNone; } ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type) { - assert(is_valid_vector_elem_type(elem_type)); + Error err; + + bool valid_vector_elem; + if ((err = is_valid_vector_elem_type(g, elem_type, &valid_vector_elem))) { + codegen_report_errors_and_exit(g); + } + assert(valid_vector_elem); TypeId type_id = {}; type_id.id = ZigTypeIdVector; @@ -5049,7 +5109,7 @@ ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type) { } ZigType *entry = new_type_table_entry(ZigTypeIdVector); - if ((len != 0) && type_has_bits(elem_type)) { + if ((len != 0) && type_has_bits(g, elem_type)) { // Vectors can only be ints, floats, bools, or pointers. ints (inc. bools) and floats have trivially resolvable // llvm type refs. pointers we will use usize instead. LLVMTypeRef example_vector_llvm_type; @@ -5081,7 +5141,7 @@ ZigType *get_c_int_type(CodeGen *g, CIntType c_int_type) { return *get_c_int_type_ptr(g, c_int_type); } -bool handle_is_ptr(ZigType *type_entry) { +bool handle_is_ptr(CodeGen *g, ZigType *type_entry) { switch (type_entry->id) { case ZigTypeIdInvalid: case ZigTypeIdMetaType: @@ -5108,15 +5168,15 @@ bool handle_is_ptr(ZigType *type_entry) { case ZigTypeIdArray: case ZigTypeIdStruct: case ZigTypeIdFnFrame: - return type_has_bits(type_entry); + return type_has_bits(g, type_entry); case ZigTypeIdErrorUnion: - return type_has_bits(type_entry->data.error_union.payload_type); + return type_has_bits(g, type_entry->data.error_union.payload_type); case ZigTypeIdOptional: - return type_has_bits(type_entry->data.maybe.child_type) && - !type_is_nonnull_ptr(type_entry->data.maybe.child_type) && + return type_has_bits(g, type_entry->data.maybe.child_type) && + !type_is_nonnull_ptr(g, type_entry->data.maybe.child_type) && type_entry->data.maybe.child_type->id != ZigTypeIdErrorSet; case ZigTypeIdUnion: - return type_has_bits(type_entry) && type_entry->data.unionation.gen_field_count != 0; + return type_has_bits(g, type_entry) && type_entry->data.unionation.gen_field_count != 0; } zig_unreachable(); @@ -5329,7 +5389,7 @@ static uint32_t hash_const_val(ZigValue *const_val) { // TODO better hashing algorithm return 2709806591; case ZigTypeIdOptional: - if (get_codegen_ptr_type(const_val->type) != nullptr) { + if (get_src_ptr_type(const_val->type) != nullptr) { return hash_const_val_ptr(const_val) * 1992916303; } else if (const_val->type->data.maybe.child_type->id == ZigTypeIdErrorSet) { return hash_const_val_error_set(const_val) * 3147031929; @@ -5455,7 +5515,7 @@ static bool can_mutate_comptime_var_state(ZigValue *value) { return false; case ZigTypeIdOptional: - if (get_codegen_ptr_type(value->type) != nullptr) + if (get_src_ptr_type(value->type) != nullptr) return value->data.x_ptr.mut == ConstPtrMutComptimeVar; if (value->data.x_optional == nullptr) return false; @@ -5593,11 +5653,13 @@ bool fn_eval_eql(Scope *a, Scope *b) { } // Deprecated. Use type_has_bits2. -bool type_has_bits(ZigType *type_entry) { - assert(type_entry != nullptr); - assert(!type_is_invalid(type_entry)); - assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown)); - return type_entry->abi_size != 0; +bool type_has_bits(CodeGen *g, ZigType *type_entry) { + Error err; + bool result; + if ((err = type_has_bits2(g, type_entry, &result))) { + codegen_report_errors_and_exit(g); + } + return result; } // Whether the type has bits at runtime. @@ -5687,7 +5749,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { case ZigTypeIdEnum: case ZigTypeIdInt: case ZigTypeIdVector: - return type_has_bits(type_entry) ? OnePossibleValueNo : OnePossibleValueYes; + return type_has_bits(g, type_entry) ? OnePossibleValueNo : OnePossibleValueYes; case ZigTypeIdPointer: { ZigType *elem_type = type_entry->data.pointer.child_type; // If the recursive function call asks, then we are not one possible value. @@ -6365,7 +6427,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { } if (await->base.base.ref_count == 0) continue; - if (!type_has_bits(await->base.value->type)) + if (!type_has_bits(g, await->base.value->type)) continue; await->result_loc = ir_create_alloca(g, await->base.base.scope, await->base.base.source_node, fn, await->base.value->type, ""); @@ -6406,7 +6468,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { continue; if ((err = type_resolve(g, instruction->value->type, ResolveStatusZeroBitsKnown))) return ErrorSemanticAnalyzeFail; - if (!type_has_bits(instruction->value->type)) + if (!type_has_bits(g, instruction->value->type)) continue; if (scope_needs_spill(instruction->base.scope)) { instruction->spill = ir_create_alloca(g, instruction->base.scope, instruction->base.source_node, @@ -6465,7 +6527,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { ZigType *ptr_type = instruction->base.value->type; assert(ptr_type->id == ZigTypeIdPointer); ZigType *child_type = resolve_type_isf(ptr_type->data.pointer.child_type); - if (!type_has_bits(child_type)) + if (!type_has_bits(g, child_type)) continue; if (instruction->base.base.ref_count == 0) continue; @@ -6763,7 +6825,7 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) { if (bigint_cmp(&union1->tag, &union2->tag) == CmpEQ) { TypeUnionField *field = find_union_field_by_tag(a->type, &union1->tag); assert(field != nullptr); - if (!type_has_bits(field->type_entry)) + if (!type_has_bits(g, field->type_entry)) return true; assert(find_union_field_by_tag(a->type, &union2->tag) != nullptr); return const_values_equal(g, union1->payload, union2->payload); @@ -6826,7 +6888,7 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) { case ZigTypeIdNull: zig_panic("TODO"); case ZigTypeIdOptional: - if (get_codegen_ptr_type(a->type) != nullptr) + if (get_src_ptr_type(a->type) != nullptr) return const_values_equal_ptr(a, b); if (a->data.x_optional == nullptr || b->data.x_optional == nullptr) { return (a->data.x_optional == nullptr && b->data.x_optional == nullptr); @@ -7097,7 +7159,7 @@ void render_const_value(CodeGen *g, Buf *buf, ZigValue *const_val) { } case ZigTypeIdOptional: { - if (get_codegen_ptr_type(const_val->type) != nullptr) + if (get_src_ptr_type(const_val->type) != nullptr) return render_const_val_ptr(g, buf, const_val, type_entry->data.maybe.child_type); if (type_entry->data.maybe.child_type->id == ZigTypeIdErrorSet) return render_const_val_err_set(g, buf, const_val, type_entry->data.maybe.child_type); @@ -7881,8 +7943,12 @@ static X64CABIClass type_system_V_abi_x86_64_class(CodeGen *g, ZigType *ty, size } X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) { + Error err; + const size_t ty_size = type_size(g, ty); - if (get_codegen_ptr_type(ty) != nullptr) + ZigType *ptr_type; + if ((err = get_codegen_ptr_type(g, ty, &ptr_type))) return X64CABIClass_Unknown; + if (ptr_type != nullptr) return X64CABIClass_INTEGER; if (g->zig_target->os == OsWindows || g->zig_target->os == OsUefi) { @@ -7898,14 +7964,32 @@ X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) { } // NOTE this does not depend on x86_64 -bool type_is_c_abi_int(CodeGen *g, ZigType *ty) { - return (ty->id == ZigTypeIdInt || +Error type_is_c_abi_int(CodeGen *g, ZigType *ty, bool *result) { + if (ty->id == ZigTypeIdInt || ty->id == ZigTypeIdFloat || ty->id == ZigTypeIdBool || ty->id == ZigTypeIdEnum || ty->id == ZigTypeIdVoid || - ty->id == ZigTypeIdUnreachable || - get_codegen_ptr_type(ty) != nullptr); + ty->id == ZigTypeIdUnreachable) + { + *result = true; + return ErrorNone; + } + + Error err; + ZigType *ptr_type; + if ((err = get_codegen_ptr_type(g, ty, &ptr_type))) return err; + *result = ptr_type != nullptr; + return ErrorNone; +} + +bool type_is_c_abi_int_bail(CodeGen *g, ZigType *ty) { + Error err; + bool result; + if ((err = type_is_c_abi_int(g, ty, &result))) + codegen_report_errors_and_exit(g); + + return result; } uint32_t get_host_int_bytes(CodeGen *g, ZigType *struct_type, TypeStructField *field) { @@ -8036,7 +8120,7 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return; } - if (!type_has_bits(child_type)) { + if (!type_has_bits(g, child_type)) { LLVMTypeRef element_types[] = { usize_llvm_type, }; @@ -8145,7 +8229,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS } if (struct_type->data.structure.resolve_status < ResolveStatusLLVMFwdDecl) { - struct_type->llvm_type = type_has_bits(struct_type) ? + struct_type->llvm_type = type_has_bits(g, struct_type) ? LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&struct_type->name)) : LLVMVoidType(); unsigned dwarf_kind = ZigLLVMTag_DW_structure_type(); struct_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, @@ -8175,7 +8259,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS for (size_t i = 0; i < field_count; i += 1) { TypeStructField *field = struct_type->data.structure.fields[i]; ZigType *field_type = field->type_entry; - if (!type_has_bits(field_type)) + if (!type_has_bits(g, field_type)) continue; (void)get_llvm_type(g, field_type); if (struct_type->data.structure.resolve_status >= wanted_resolve_status) return; @@ -8189,7 +8273,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS for (size_t i = 0; i < field_count; i += 1) { TypeStructField *field = struct_type->data.structure.fields[i]; ZigType *field_type = field->type_entry; - if (field->is_comptime || !type_has_bits(field_type)) + if (field->is_comptime || !type_has_bits(g, field_type)) continue; LLVMTypeRef field_llvm_type = get_llvm_type(g, field_type); size_t llvm_field_abi_align = LLVMABIAlignmentOfType(g->target_data_ref, field_llvm_type); @@ -8200,7 +8284,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS TypeStructField *field = struct_type->data.structure.fields[i]; ZigType *field_type = field->type_entry; - if (field->is_comptime || !type_has_bits(field_type)) { + if (field->is_comptime || !type_has_bits(g, field_type)) { field->gen_index = SIZE_MAX; continue; } @@ -8247,7 +8331,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS // find the next non-zero-byte field for offset calculations size_t next_src_field_index = i + 1; for (; next_src_field_index < field_count; next_src_field_index += 1) { - if (type_has_bits(struct_type->data.structure.fields[next_src_field_index]->type_entry)) + if (type_has_bits(g, struct_type->data.structure.fields[next_src_field_index]->type_entry)) break; } size_t next_abi_align; @@ -8293,7 +8377,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS gen_field_index += 1; } - if (type_has_bits(struct_type)) { + if (type_has_bits(g, struct_type)) { assert(struct_type->data.structure.gen_field_count == gen_field_index); LLVMStructSetBody(struct_type->llvm_type, element_types, (unsigned)struct_type->data.structure.gen_field_count, packed); @@ -8405,7 +8489,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu ZigType *import = get_scope_import(scope); AstNode *decl_node = enum_type->data.enumeration.decl_node; - if (!type_has_bits(enum_type)) { + if (!type_has_bits(g, enum_type)) { enum_type->llvm_type = g->builtin_types.entry_void->llvm_type; enum_type->llvm_di_type = make_empty_namespace_llvm_di_type(g, import, buf_ptr(&enum_type->name), decl_node); @@ -8487,7 +8571,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta uint32_t field_count = union_type->data.unionation.src_field_count; for (uint32_t i = 0; i < field_count; i += 1) { TypeUnionField *union_field = &union_type->data.unionation.fields[i]; - if (!type_has_bits(union_field->type_entry)) + if (!type_has_bits(g, union_field->type_entry)) continue; ZigLLVMDIType *field_di_type = get_llvm_di_type(g, union_field->type_entry); @@ -8506,7 +8590,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta } - if (tag_type == nullptr || !type_has_bits(tag_type)) { + if (tag_type == nullptr || !type_has_bits(g, tag_type)) { assert(most_aligned_union_member != nullptr); size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->type_entry->abi_size; @@ -8616,7 +8700,7 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus if (resolve_pointer_zero_bits(g, type) != ErrorNone) zig_unreachable(); - if (!type_has_bits(type)) { + if (!type_has_bits(g, type)) { type->llvm_type = g->builtin_types.entry_void->llvm_type; type->llvm_di_type = g->builtin_types.entry_void->llvm_di_type; return; @@ -8669,7 +8753,7 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus static void resolve_llvm_types_integer(CodeGen *g, ZigType *type) { if (type->llvm_di_type != nullptr) return; - if (!type_has_bits(type)) { + if (!type_has_bits(g, type)) { type->llvm_type = g->builtin_types.entry_void->llvm_type; type->llvm_di_type = g->builtin_types.entry_void->llvm_di_type; return; @@ -8705,14 +8789,14 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type, ResolveStatus ZigLLVMDIType *bool_llvm_di_type = get_llvm_di_type(g, g->builtin_types.entry_bool); ZigType *child_type = type->data.maybe.child_type; - if (!type_has_bits(child_type)) { + if (!type_has_bits(g, child_type)) { type->llvm_type = bool_llvm_type; type->llvm_di_type = bool_llvm_di_type; type->data.maybe.resolve_status = ResolveStatusLLVMFull; return; } - if (type_is_nonnull_ptr(child_type) || child_type->id == ZigTypeIdErrorSet) { + if (type_is_nonnull_ptr(g, child_type) || child_type->id == ZigTypeIdErrorSet) { type->llvm_type = get_llvm_type(g, child_type); type->llvm_di_type = get_llvm_di_type(g, child_type); type->data.maybe.resolve_status = ResolveStatusLLVMFull; @@ -8778,11 +8862,11 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) { ZigType *payload_type = type->data.error_union.payload_type; ZigType *err_set_type = type->data.error_union.err_set_type; - if (!type_has_bits(payload_type)) { - assert(type_has_bits(err_set_type)); + if (!type_has_bits(g, payload_type)) { + assert(type_has_bits(g, err_set_type)); type->llvm_type = get_llvm_type(g, err_set_type); type->llvm_di_type = get_llvm_di_type(g, err_set_type); - } else if (!type_has_bits(err_set_type)) { + } else if (!type_has_bits(g, err_set_type)) { type->llvm_type = get_llvm_type(g, payload_type); type->llvm_di_type = get_llvm_di_type(g, payload_type); } else { @@ -8852,7 +8936,7 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) { static void resolve_llvm_types_array(CodeGen *g, ZigType *type) { if (type->llvm_di_type != nullptr) return; - if (!type_has_bits(type)) { + if (!type_has_bits(g, type)) { type->llvm_type = g->builtin_types.entry_void->llvm_type; type->llvm_di_type = g->builtin_types.entry_void->llvm_di_type; return; @@ -8893,7 +8977,7 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) { if (is_async) { gen_return_type = g->builtin_types.entry_void; param_di_types.append(nullptr); - } else if (!type_has_bits(fn_type_id->return_type)) { + } else if (!type_has_bits(g, fn_type_id->return_type)) { gen_return_type = g->builtin_types.entry_void; param_di_types.append(nullptr); } else if (first_arg_return) { @@ -8940,11 +9024,11 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) { gen_param_info->src_index = i; gen_param_info->gen_index = SIZE_MAX; - if (is_c_abi || !type_has_bits(type_entry)) + if (is_c_abi || !type_has_bits(g, type_entry)) continue; ZigType *gen_type; - if (handle_is_ptr(type_entry)) { + if (handle_is_ptr(g, type_entry)) { gen_type = get_pointer_to_type(g, type_entry, true); gen_param_info->is_byval = true; } else { @@ -9098,7 +9182,7 @@ static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, Re field_types.append(usize_type_ref); // resume_index field_types.append(usize_type_ref); // awaiter - bool have_result_type = result_type != nullptr && type_has_bits(result_type); + bool have_result_type = result_type != nullptr && type_has_bits(g, result_type); if (have_result_type) { field_types.append(get_llvm_type(g, ptr_result_type)); // result_ptr_callee field_types.append(get_llvm_type(g, ptr_result_type)); // result_ptr_awaiter @@ -9379,7 +9463,7 @@ bool is_opt_err_set(ZigType *ty) { bool type_has_optional_repr(ZigType *ty) { if (ty->id != ZigTypeIdOptional) { return false; - } else if (get_codegen_ptr_type(ty) != nullptr) { + } else if (get_src_ptr_type(ty) != nullptr) { return false; } else if (is_opt_err_set(ty)) { return false; @@ -9471,6 +9555,58 @@ bool type_is_numeric(ZigType *ty) { zig_unreachable(); } +static void dump_value_indent_error_set(ZigValue *val, int indent) { + fprintf(stderr, "\n"); +} + +static void dump_value_indent(ZigValue *val, int indent); + +static void dump_value_indent_ptr(ZigValue *val, int indent) { + switch (val->data.x_ptr.special) { + case ConstPtrSpecialInvalid: + fprintf(stderr, "\n"); + return; + case ConstPtrSpecialNull: + fprintf(stderr, "\n"); + return; + case ConstPtrSpecialRef: + fprintf(stderr, "data.x_ptr.data.ref.pointee, indent + 1); + break; + case ConstPtrSpecialBaseStruct: { + ZigValue *struct_val = val->data.x_ptr.data.base_struct.struct_val; + size_t field_index = val->data.x_ptr.data.base_struct.field_index; + fprintf(stderr, "data.x_struct.fields[field_index]; + if (field_val != nullptr) { + dump_value_indent(field_val, indent + 1); + } else { + for (int i = 0; i < indent; i += 1) { + fprintf(stderr, " "); + } + fprintf(stderr, "(invalid null field)\n"); + } + } + break; + } + case ConstPtrSpecialBaseOptionalPayload: { + ZigValue *optional_val = val->data.x_ptr.data.base_optional_payload.optional_val; + fprintf(stderr, "\n"); +} + static void dump_value_indent(ZigValue *val, int indent) { for (int i = 0; i < indent; i += 1) { fprintf(stderr, " "); @@ -9548,15 +9684,20 @@ static void dump_value_indent(ZigValue *val, int indent) { return; case ZigTypeIdOptional: - fprintf(stderr, "<\n"); - dump_value_indent(val->data.x_optional, indent + 1); + if (get_src_ptr_type(val->type) != nullptr) { + return dump_value_indent_ptr(val, indent); + } else if (val->type->data.maybe.child_type->id == ZigTypeIdErrorSet) { + return dump_value_indent_error_set(val, indent); + } else { + fprintf(stderr, "<\n"); + dump_value_indent(val->data.x_optional, indent + 1); - for (int i = 0; i < indent; i += 1) { - fprintf(stderr, " "); + for (int i = 0; i < indent; i += 1) { + fprintf(stderr, " "); + } + fprintf(stderr, ">\n"); + return; } - fprintf(stderr, ">\n"); - return; - case ZigTypeIdErrorUnion: if (val->data.x_err_union.payload != nullptr) { fprintf(stderr, "<\n"); @@ -9572,52 +9713,14 @@ static void dump_value_indent(ZigValue *val, int indent) { return; case ZigTypeIdPointer: - switch (val->data.x_ptr.special) { - case ConstPtrSpecialInvalid: - fprintf(stderr, "\n"); - return; - case ConstPtrSpecialRef: - fprintf(stderr, "data.x_ptr.data.ref.pointee, indent + 1); - break; - case ConstPtrSpecialBaseStruct: { - ZigValue *struct_val = val->data.x_ptr.data.base_struct.struct_val; - size_t field_index = val->data.x_ptr.data.base_struct.field_index; - fprintf(stderr, "data.x_struct.fields[field_index]; - if (field_val != nullptr) { - dump_value_indent(field_val, indent + 1); - } else { - for (int i = 0; i < indent; i += 1) { - fprintf(stderr, " "); - } - fprintf(stderr, "(invalid null field)\n"); - } - } - break; - } - case ConstPtrSpecialBaseOptionalPayload: { - ZigValue *optional_val = val->data.x_ptr.data.base_optional_payload.optional_val; - fprintf(stderr, "\n"); - return; + return dump_value_indent_ptr(val, indent); + + case ZigTypeIdErrorSet: + return dump_value_indent_error_set(val, indent); case ZigTypeIdVector: case ZigTypeIdArray: case ZigTypeIdNull: - case ZigTypeIdErrorSet: case ZigTypeIdEnum: case ZigTypeIdUnion: case ZigTypeIdFn: diff --git a/src/analyze.hpp b/src/analyze.hpp index eb3781789d..678c62cc08 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -44,14 +44,20 @@ ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry); ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name); ZigType *get_test_fn_type(CodeGen *g); ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type); -bool handle_is_ptr(ZigType *type_entry); +bool handle_is_ptr(CodeGen *g, ZigType *type_entry); -bool type_has_bits(ZigType *type_entry); +bool type_has_bits(CodeGen *g, ZigType *type_entry); Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result); Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result); bool ptr_allows_addr_zero(ZigType *ptr_type); -bool type_is_nonnull_ptr(ZigType *type); + +// Deprecated, use `type_is_nonnull_ptr2` +bool type_is_nonnull_ptr(CodeGen *g, ZigType *type); +Error type_is_nonnull_ptr2(CodeGen *g, ZigType *type, bool *result); + +ZigType *get_codegen_ptr_type_bail(CodeGen *g, ZigType *type); +Error get_codegen_ptr_type(CodeGen *g, ZigType *type, ZigType **result); enum SourceKind { SourceKindRoot, @@ -68,7 +74,6 @@ Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name); void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool allow_lazy); ZigType *get_src_ptr_type(ZigType *type); -ZigType *get_codegen_ptr_type(ZigType *type); uint32_t get_ptr_align(CodeGen *g, ZigType *type); bool get_ptr_const(ZigType *type); ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry); @@ -87,7 +92,7 @@ TypeUnionField *find_union_field_by_tag(ZigType *type_entry, const BigInt *tag); bool is_ref(ZigType *type_entry); bool is_array_ref(ZigType *type_entry); bool is_container_ref(ZigType *type_entry); -bool is_valid_vector_elem_type(ZigType *elem_type); +Error is_valid_vector_elem_type(CodeGen *g, ZigType *elem_type, bool *result); void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node); ZigFn *scope_fn_entry(Scope *scope); ZigPackage *scope_package(Scope *scope); @@ -223,7 +228,8 @@ Error ATTRIBUTE_MUST_USE file_fetch(CodeGen *g, Buf *resolved_path, Buf *content void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk); X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty); -bool type_is_c_abi_int(CodeGen *g, ZigType *ty); +bool type_is_c_abi_int_bail(CodeGen *g, ZigType *ty); +Error type_is_c_abi_int(CodeGen *g, ZigType *ty, bool *result); bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id); const char *container_string(ContainerKind kind); diff --git a/src/codegen.cpp b/src/codegen.cpp index 40b8df09e0..51e2f4625e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -313,7 +313,7 @@ struct CalcLLVMFieldIndex { }; static void calc_llvm_field_index_add(CodeGen *g, CalcLLVMFieldIndex *calc, ZigType *ty) { - if (!type_has_bits(ty)) return; + if (!type_has_bits(g, ty)) return; uint32_t ty_align = get_abi_alignment(g, ty); if (calc->offset % ty_align != 0) { uint32_t llvm_align = LLVMABIAlignmentOfType(g->target_data_ref, get_llvm_type(g, ty)); @@ -334,7 +334,7 @@ static void frame_index_trace_arg_calc(CodeGen *g, CalcLLVMFieldIndex *calc, Zig calc_llvm_field_index_add(g, calc, g->builtin_types.entry_usize); // resume index calc_llvm_field_index_add(g, calc, g->builtin_types.entry_usize); // awaiter index - if (type_has_bits(return_type)) { + if (type_has_bits(g, return_type)) { calc_llvm_field_index_add(g, calc, g->builtin_types.entry_usize); // *ReturnType (callee's) calc_llvm_field_index_add(g, calc, g->builtin_types.entry_usize); // *ReturnType (awaiter's) calc_llvm_field_index_add(g, calc, return_type); // ReturnType @@ -383,7 +383,7 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) { return UINT32_MAX; } ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; - bool first_arg_ret = type_has_bits(return_type) && handle_is_ptr(return_type); + bool first_arg_ret = type_has_bits(g, return_type) && handle_is_ptr(g, return_type); return first_arg_ret ? 1 : 0; } @@ -581,9 +581,9 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { addLLVMArgAttr(llvm_fn, 0, "nonnull"); } else { unsigned init_gen_i = 0; - if (!type_has_bits(return_type)) { + if (!type_has_bits(g, return_type)) { // nothing to do - } else if (type_is_nonnull_ptr(return_type)) { + } else if (type_is_nonnull_ptr(g, return_type)) { addLLVMAttr(llvm_fn, 0, "nonnull"); } else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) { // Sret pointers must not be address 0 @@ -859,8 +859,8 @@ static LLVMValueRef gen_load(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, co } static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, ZigType *type, ZigType *ptr_type) { - if (type_has_bits(type)) { - if (handle_is_ptr(type)) { + if (type_has_bits(g, type)) { + if (handle_is_ptr(g, type)) { return ptr; } else { assert(ptr_type->id == ZigTypeIdPointer); @@ -1671,10 +1671,10 @@ static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, assert(ptr_type->id == ZigTypeIdPointer); ZigType *child_type = ptr_type->data.pointer.child_type; - if (!type_has_bits(child_type)) + if (!type_has_bits(g, child_type)) return; - if (handle_is_ptr(child_type)) { + if (handle_is_ptr(g, child_type)) { assert(LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMPointerTypeKind); assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind); @@ -1782,7 +1782,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstGen *instruction) { render_const_val(g, instruction->value, ""); // we might have to do some pointer casting here due to the way union // values are rendered with a type other than the one we expect - if (handle_is_ptr(instruction->value->type)) { + if (handle_is_ptr(g, instruction->value->type)) { render_const_val_global(g, instruction->value, ""); ZigType *ptr_type = get_pointer_to_type(g, instruction->value->type, true); instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value->llvm_global, get_llvm_type(g, ptr_type), ""); @@ -1879,14 +1879,14 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ break; } - if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat || ty->id == ZigTypeIdVector || + if (type_is_c_abi_int_bail(g, ty) || ty->id == ZigTypeIdFloat || ty->id == ZigTypeIdVector || ty->id == ZigTypeIdInt // TODO investigate if we need to change this ) { switch (fn_walk->id) { case FnWalkIdAttrs: { - ZigType *ptr_type = get_codegen_ptr_type(ty); + ZigType *ptr_type = get_codegen_ptr_type_bail(g, ty); if (ptr_type != nullptr) { - if (type_is_nonnull_ptr(ty)) { + if (type_is_nonnull_ptr(g, ty)) { addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); } if (ptr_type->data.pointer.is_const) { @@ -1928,7 +1928,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ { // Arrays are just pointers if (ty->id == ZigTypeIdArray) { - assert(handle_is_ptr(ty)); + assert(handle_is_ptr(g, ty)); switch (fn_walk->id) { case FnWalkIdAttrs: // arrays passed to C ABI functions may not be at address 0 @@ -1965,7 +1965,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ X64CABIClass abi_class = type_c_abi_x86_64_class(g, ty); size_t ty_size = type_size(g, ty); if (abi_class == X64CABIClass_MEMORY || abi_class == X64CABIClass_MEMORY_nobyval) { - assert(handle_is_ptr(ty)); + assert(handle_is_ptr(g, ty)); switch (fn_walk->id) { case FnWalkIdAttrs: if (abi_class != X64CABIClass_MEMORY_nobyval) { @@ -2088,7 +2088,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) { for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) { IrInstGen *param_instruction = instruction->args[call_i]; ZigType *param_type = param_instruction->value->type; - if (is_var_args || type_has_bits(param_type)) { + if (is_var_args || type_has_bits(g, param_type)) { LLVMValueRef param_value = ir_llvm_value(g, param_instruction); assert(param_value); fn_walk->data.call.gen_param_values->append(param_value); @@ -2119,10 +2119,10 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) { if ((param_type->id == ZigTypeIdPointer && param_type->data.pointer.is_const) || is_byval) { addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "readonly"); } - if (get_codegen_ptr_type(param_type) != nullptr) { + if (get_codegen_ptr_type_bail(g, param_type) != nullptr) { addLLVMArgAttrInt(llvm_fn, (unsigned)gen_index, "align", get_ptr_align(g, param_type)); } - if (type_is_nonnull_ptr(param_type)) { + if (type_is_nonnull_ptr(g, param_type)) { addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "nonnull"); } break; @@ -2137,7 +2137,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) { assert(variable); assert(variable->value_ref); - if (!handle_is_ptr(variable->var_type) && !fn_is_async(fn_walk->data.inits.fn)) { + if (!handle_is_ptr(g, variable->var_type) && !fn_is_async(fn_walk->data.inits.fn)) { clear_debug_source_node(g); ZigType *fn_type = fn_table_entry->type_entry; unsigned gen_arg_index = fn_type->data.fn.gen_param_info[variable->src_arg_index].gen_index; @@ -2404,12 +2404,12 @@ static void gen_async_return(CodeGen *g, IrInstGenReturn *instruction) { LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; ZigType *operand_type = (instruction->operand != nullptr) ? instruction->operand->value->type : nullptr; - bool operand_has_bits = (operand_type != nullptr) && type_has_bits(operand_type); + bool operand_has_bits = (operand_type != nullptr) && type_has_bits(g, operand_type); ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type; - bool ret_type_has_bits = type_has_bits(ret_type); + bool ret_type_has_bits = type_has_bits(g, ret_type); if (operand_has_bits && instruction->operand != nullptr) { - bool need_store = instruction->operand->value->special != ConstValSpecialRuntime || !handle_is_ptr(ret_type); + bool need_store = instruction->operand->value->special != ConstValSpecialRuntime || !handle_is_ptr(g, ret_type); if (need_store) { // It didn't get written to the result ptr. We do that now. ZigType *ret_ptr_type = get_pointer_to_type(g, ret_type, true); @@ -2512,7 +2512,7 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutableGen *executable, Ir gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value); LLVMBuildRetVoid(g->builder); } else if (g->cur_fn->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync && - handle_is_ptr(g->cur_fn->type_entry->data.fn.fn_type_id.return_type)) + handle_is_ptr(g, g->cur_fn->type_entry->data.fn.fn_type_id.return_type)) { if (instruction->operand == nullptr) { LLVMValueRef by_val_value = gen_load_untyped(g, g->cur_ret_ptr, 0, false, ""); @@ -2883,7 +2883,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutableGen *executable, } else if (scalar_type->id == ZigTypeIdEnum || scalar_type->id == ZigTypeIdErrorSet || scalar_type->id == ZigTypeIdBool || - get_codegen_ptr_type(scalar_type) != nullptr) + get_codegen_ptr_type_bail(g, scalar_type) != nullptr) { LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false); return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, ""); @@ -3149,7 +3149,7 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutableGen ZigType *array_type = actual_type->data.pointer.child_type; assert(array_type->id == ZigTypeIdArray); - if (type_has_bits(actual_type)) { + if (type_has_bits(g, actual_type)) { LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, ""); LLVMValueRef indices[] = { LLVMConstNull(g->builtin_types.entry_usize->llvm_type), @@ -3175,7 +3175,7 @@ static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutableGen *executable, IrInstGenPtrCast *instruction) { ZigType *wanted_type = instruction->base.value->type; - if (!type_has_bits(wanted_type)) { + if (!type_has_bits(g, wanted_type)) { return nullptr; } LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); @@ -3204,8 +3204,8 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutableGen *executable, ZigType *actual_type = instruction->operand->value->type; LLVMValueRef value = ir_llvm_value(g, instruction->operand); - bool wanted_is_ptr = handle_is_ptr(wanted_type); - bool actual_is_ptr = handle_is_ptr(actual_type); + bool wanted_is_ptr = handle_is_ptr(g, wanted_type); + bool actual_is_ptr = handle_is_ptr(g, actual_type); if (wanted_is_ptr == actual_is_ptr) { // We either bitcast the value directly or bitcast the pointer which does a pointer cast LLVMTypeRef wanted_type_ref = wanted_is_ptr ? @@ -3352,9 +3352,9 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutableGen *executable g->err_tag_type, wanted_type, target_val); } else if (actual_type->id == ZigTypeIdErrorUnion) { // this should have been a compile time constant - assert(type_has_bits(actual_type->data.error_union.err_set_type)); + assert(type_has_bits(g, actual_type->data.error_union.err_set_type)); - if (!type_has_bits(actual_type->data.error_union.payload_type)) { + if (!type_has_bits(g, actual_type->data.error_union.payload_type)) { return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base), g->err_tag_type, wanted_type, target_val); } else { @@ -3442,7 +3442,7 @@ static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutableGen *executable, } static void render_decl_var(CodeGen *g, ZigVar *var) { - if (!type_has_bits(var->var_type)) + if (!type_has_bits(g, var->var_type)) return; var->value_ref = ir_llvm_value(g, var->ptr_instruction); @@ -3460,7 +3460,7 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenLoadPtr *instruction) { ZigType *child_type = instruction->base.value->type; - if (!type_has_bits(child_type)) + if (!type_has_bits(g, child_type)) return nullptr; LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); @@ -3495,7 +3495,7 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutableGen *executable, LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false); LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, ""); - if (handle_is_ptr(child_type)) { + if (handle_is_ptr(g, child_type)) { LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); LLVMTypeRef same_size_int = LLVMIntType(size_in_bits); LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, shifted_value, same_size_int, ""); @@ -3642,7 +3642,7 @@ static void gen_valgrind_undef(CodeGen *g, LLVMValueRef dest_ptr, LLVMValueRef b } static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr) { - assert(type_has_bits(value_type)); + assert(type_has_bits(g, value_type)); uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, get_llvm_type(g, value_type)); assert(size_bytes > 0); assert(ptr_align_bytes > 0); @@ -3708,7 +3708,7 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutableGen *executable, I if (instruction->base.value->special != ConstValSpecialRuntime) return ir_llvm_value(g, &instruction->base); ZigVar *var = instruction->var; - if (type_has_bits(var->var_type)) { + if (type_has_bits(g, var->var_type)) { assert(var->value_ref); return var->value_ref; } else { @@ -3719,7 +3719,7 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutableGen *executable, I static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenReturnPtr *instruction) { - if (!type_has_bits(instruction->base.value->type)) + if (!type_has_bits(g, instruction->base.value->type)) return nullptr; ir_assert(g->cur_ret_ptr != nullptr, &instruction->base); return g->cur_ret_ptr; @@ -3733,7 +3733,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutableGen *executable, LLVMValueRef subscript_value = ir_llvm_value(g, instruction->elem_index); assert(subscript_value); - if (!type_has_bits(array_type)) + if (!type_has_bits(g, array_type)) return nullptr; bool safety_check_on = ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on; @@ -3793,7 +3793,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutableGen *executable, assert(array_type->data.structure.special == StructSpecialSlice); ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; - if (!type_has_bits(ptr_type)) { + if (!type_has_bits(g, ptr_type)) { if (safety_check_on) { assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMIntegerTypeKind); add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, array_ptr); @@ -3872,7 +3872,7 @@ static void render_async_spills(CodeGen *g) { for (size_t var_i = 0; var_i < g->cur_fn->variable_list.length; var_i += 1) { ZigVar *var = g->cur_fn->variable_list.at(var_i); - if (!type_has_bits(var->var_type)) { + if (!type_has_bits(g, var->var_type)) { continue; } if (ir_get_var_is_comptime(var)) @@ -3992,7 +3992,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; ZigType *src_return_type = fn_type_id->return_type; - bool ret_has_bits = type_has_bits(src_return_type); + bool ret_has_bits = type_has_bits(g, src_return_type); CallingConvention cc = fn_type->data.fn.fn_type_id.cc; @@ -4312,7 +4312,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn gen_assert_resume_id(g, &instruction->base, ResumeIdReturn, PanicMsgIdResumedAnAwaitingFn, nullptr); render_async_var_decls(g, instruction->base.base.scope); - if (!type_has_bits(src_return_type)) + if (!type_has_bits(g, src_return_type)) return nullptr; if (result_loc != nullptr) { @@ -4372,7 +4372,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn } else if (first_arg_ret) { set_call_instr_sret(g, result); return result_loc; - } else if (handle_is_ptr(src_return_type)) { + } else if (handle_is_ptr(g, src_return_type)) { LLVMValueRef store_instr = LLVMBuildStore(g->builder, result, result_loc); LLVMSetAlignment(store_instr, get_ptr_align(g, instruction->result_loc->value->type)); return result_loc; @@ -4397,7 +4397,7 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutableGen *exec ZigType *struct_ptr_type = instruction->struct_ptr->value->type; TypeStructField *field = instruction->field; - if (!type_has_bits(field->type_entry)) + if (!type_has_bits(g, field->type_entry)) return nullptr; if (struct_ptr_type->id == ZigTypeIdPointer && @@ -4448,9 +4448,9 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutableGen *execu TypeUnionField *field = instruction->field; - if (!type_has_bits(field->type_entry)) { + if (!type_has_bits(g, field->type_entry)) { ZigType *tag_type = union_type->data.unionation.tag_type; - if (!instruction->initializing || tag_type == nullptr || !type_has_bits(tag_type)) + if (!instruction->initializing || tag_type == nullptr || !type_has_bits(g, tag_type)) return nullptr; // The field has no bits but we still have to change the discriminant @@ -4672,10 +4672,10 @@ static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueR (maybe_type->id == ZigTypeIdPointer && maybe_type->data.pointer.allow_zero)); ZigType *child_type = maybe_type->data.maybe.child_type; - if (!type_has_bits(child_type)) + if (!type_has_bits(g, child_type)) return maybe_handle; - bool is_scalar = !handle_is_ptr(maybe_type); + bool is_scalar = !handle_is_ptr(g, maybe_type); if (is_scalar) return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(get_llvm_type(g, maybe_type)), ""); @@ -4713,14 +4713,14 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutableGen *e LLVMPositionBuilderAtEnd(g->builder, ok_block); } - if (!type_has_bits(child_type)) { + if (!type_has_bits(g, child_type)) { if (instruction->initializing) { LLVMValueRef non_null_bit = LLVMConstInt(LLVMInt1Type(), 1, false); gen_store_untyped(g, non_null_bit, base_ptr, 0, false); } return nullptr; } else { - bool is_scalar = !handle_is_ptr(maybe_type); + bool is_scalar = !handle_is_ptr(g, maybe_type); if (is_scalar) { return base_ptr; } else { @@ -4899,11 +4899,11 @@ static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutableGen *executable, } static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutableGen *executable, IrInstGenPhi *instruction) { - if (!type_has_bits(instruction->base.value->type)) + if (!type_has_bits(g, instruction->base.value->type)) return nullptr; LLVMTypeRef phi_type; - if (handle_is_ptr(instruction->base.value->type)) { + if (handle_is_ptr(g, instruction->base.value->type)) { phi_type = LLVMPointerType(get_llvm_type(g,instruction->base.value->type), 0); } else { phi_type = get_llvm_type(g, instruction->base.value->type); @@ -4921,7 +4921,7 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutableGen *executable, IrIns } static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrInstGenRef *instruction) { - if (!type_has_bits(instruction->base.value->type)) { + if (!type_has_bits(g, instruction->base.value->type)) { return nullptr; } if (instruction->operand->id == IrInstGenIdCall) { @@ -4931,7 +4931,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns } } LLVMValueRef value = ir_llvm_value(g, instruction->operand); - if (handle_is_ptr(instruction->operand->value->type)) { + if (handle_is_ptr(g, instruction->operand->value->type)) { return value; } else { LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); @@ -5232,20 +5232,20 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I assert(optional_type->id == ZigTypeIdOptional); ZigType *child_type = optional_type->data.maybe.child_type; - if (!handle_is_ptr(optional_type)) { + if (!handle_is_ptr(g, optional_type)) { LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, ""); LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, ""); return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, ""); } // When the cmpxchg is discarded, the result location will have no bits. - if (!type_has_bits(instruction->result_loc->value->type)) { + if (!type_has_bits(g, instruction->result_loc->value->type)) { return nullptr; } LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); ir_assert(result_loc != nullptr, &instruction->base); - ir_assert(type_has_bits(child_type), &instruction->base); + ir_assert(type_has_bits(g, child_type), &instruction->base); LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, ""); LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, ""); @@ -5373,7 +5373,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI } } } - if (!type_has_bits(array_type)) { + if (!type_has_bits(g, array_type)) { LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, ""); // TODO if runtime safety is on, store 0xaaaaaaa in ptr field @@ -5409,7 +5409,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI } } - if (type_has_bits(array_type)) { + if (type_has_bits(g, array_type)) { size_t gen_ptr_index = instruction->base.value->type->data.structure.fields[slice_ptr_index]->gen_index; LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, ""); LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, ""); @@ -5597,7 +5597,7 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutableGen *executable, LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->err_union); LLVMValueRef err_val; - if (type_has_bits(payload_type)) { + if (type_has_bits(g, payload_type)) { LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); err_val = gen_load_untyped(g, err_val_ptr, 0, false, ""); } else { @@ -5619,7 +5619,7 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutableGen *execu ZigType *err_union_type = ptr_type->data.pointer.child_type; ZigType *payload_type = err_union_type->data.error_union.payload_type; LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->err_union_ptr); - if (!type_has_bits(payload_type)) { + if (!type_has_bits(g, payload_type)) { return err_union_ptr; } else { // TODO assign undef to the payload @@ -5659,13 +5659,13 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutableGen *ex LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type); - if (!type_has_bits(err_union_type->data.error_union.err_set_type)) { + if (!type_has_bits(g, err_union_type->data.error_union.err_set_type)) { return err_union_handle; } if (want_safety) { LLVMValueRef err_val; - if (type_has_bits(payload_type)) { + if (type_has_bits(g, payload_type)) { LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); err_val = gen_load_untyped(g, err_val_ptr, 0, false, ""); } else { @@ -5682,7 +5682,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutableGen *ex LLVMPositionBuilderAtEnd(g->builder, ok_block); } - if (type_has_bits(payload_type)) { + if (type_has_bits(g, payload_type)) { if (instruction->initializing) { LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type)); @@ -5704,7 +5704,7 @@ static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutableGen *executa ZigType *child_type = wanted_type->data.maybe.child_type; - if (!type_has_bits(child_type)) { + if (!type_has_bits(g, child_type)) { LLVMValueRef result = LLVMConstAllOnes(LLVMInt1Type()); if (instruction->result_loc != nullptr) { LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); @@ -5714,7 +5714,7 @@ static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutableGen *executa } LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand); - if (!handle_is_ptr(wanted_type)) { + if (!handle_is_ptr(g, wanted_type)) { if (instruction->result_loc != nullptr) { LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); gen_store_untyped(g, payload_val, result_loc, 0, false); @@ -5740,7 +5740,7 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutableGen *executa LLVMValueRef err_val = ir_llvm_value(g, instruction->operand); - if (!handle_is_ptr(wanted_type)) + if (!handle_is_ptr(g, wanted_type)) return err_val; LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); @@ -5761,13 +5761,13 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutableGen *exec ZigType *payload_type = wanted_type->data.error_union.payload_type; ZigType *err_set_type = wanted_type->data.error_union.err_set_type; - if (!type_has_bits(err_set_type)) { + if (!type_has_bits(g, err_set_type)) { return ir_llvm_value(g, instruction->operand); } LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type)); - if (!type_has_bits(payload_type)) + if (!type_has_bits(g, payload_type)) return ok_err_val; @@ -5788,7 +5788,7 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutableGen *executable, ZigType *union_type = instruction->value->value->type; ZigType *tag_type = union_type->data.unionation.tag_type; - if (!type_has_bits(tag_type)) + if (!type_has_bits(g, tag_type)) return nullptr; LLVMValueRef union_val = ir_llvm_value(g, instruction->value); @@ -5825,7 +5825,7 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); LLVMValueRef operand = ir_llvm_value(g, instruction->operand); - if (get_codegen_ptr_type(operand_type) == nullptr) { + if (get_codegen_ptr_type_bail(g, operand_type) == nullptr) { return ZigLLVMBuildAtomicRMW(g->builder, op, ptr, operand, ordering, g->is_single_threaded); } @@ -5927,7 +5927,7 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutableGen *execu { ZigType *array_type = instruction->base.value->type; assert(array_type->id == ZigTypeIdArray); - assert(handle_is_ptr(array_type)); + assert(handle_is_ptr(g, array_type)); LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); LLVMValueRef vector = ir_llvm_value(g, instruction->vector); @@ -5961,7 +5961,7 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutableGen *execu { ZigType *vector_type = instruction->base.value->type; assert(vector_type->id == ZigTypeIdVector); - assert(!handle_is_ptr(vector_type)); + assert(!handle_is_ptr(g, vector_type)); LLVMValueRef array_ptr = ir_llvm_value(g, instruction->array); LLVMTypeRef vector_type_ref = get_llvm_type(g, vector_type); @@ -6057,7 +6057,7 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr, { LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; LLVMValueRef their_result_ptr = nullptr; - if (type_has_bits(result_type) && (non_async || result_loc != nullptr)) { + if (type_has_bits(g, result_type) && (non_async || result_loc != nullptr)) { LLVMValueRef their_result_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start, ""); their_result_ptr = LLVMBuildLoad(g->builder, their_result_ptr_ptr, ""); if (result_loc != nullptr) { @@ -6082,7 +6082,7 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr, ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); } - if (non_async && type_has_bits(result_type)) { + if (non_async && type_has_bits(g, result_type)) { LLVMValueRef result_ptr = (result_loc == nullptr) ? their_result_ptr : result_loc; return get_handle_value(g, result_ptr, result_type, ptr_result_type); } else { @@ -6115,7 +6115,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI // This code is as if it is running inside the suspend block. // supply the awaiter return pointer - if (type_has_bits(result_type)) { + if (type_has_bits(g, result_type)) { LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start + 1, ""); if (result_loc == nullptr) { // no copy needed @@ -6599,7 +6599,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Zig } ZigType *type_entry = const_val->type; - assert(type_has_bits(type_entry)); + assert(type_has_bits(g, type_entry)); switch (type_entry->id) { case ZigTypeIdInvalid: case ZigTypeIdMetaType: @@ -6732,7 +6732,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha { ZigValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val; assert(array_const_val->type->id == ZigTypeIdArray); - if (!type_has_bits(array_const_val->type)) { + if (!type_has_bits(g, array_const_val->type)) { if (array_const_val->type->data.array.sentinel != nullptr) { ZigValue *pointee = array_const_val->type->data.array.sentinel; render_const_val(g, pointee, ""); @@ -6758,7 +6758,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha { ZigValue *struct_const_val = const_val->data.x_ptr.data.base_struct.struct_val; assert(struct_const_val->type->id == ZigTypeIdStruct); - if (!type_has_bits(struct_const_val->type)) { + if (!type_has_bits(g, struct_const_val->type)) { // make this a null pointer ZigType *usize = g->builtin_types.entry_usize; const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), @@ -6777,7 +6777,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha { ZigValue *err_union_const_val = const_val->data.x_ptr.data.base_err_union_code.err_union_val; assert(err_union_const_val->type->id == ZigTypeIdErrorUnion); - if (!type_has_bits(err_union_const_val->type)) { + if (!type_has_bits(g, err_union_const_val->type)) { // make this a null pointer ZigType *usize = g->builtin_types.entry_usize; const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), @@ -6793,7 +6793,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha { ZigValue *err_union_const_val = const_val->data.x_ptr.data.base_err_union_payload.err_union_val; assert(err_union_const_val->type->id == ZigTypeIdErrorUnion); - if (!type_has_bits(err_union_const_val->type)) { + if (!type_has_bits(g, err_union_const_val->type)) { // make this a null pointer ZigType *usize = g->builtin_types.entry_usize; const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), @@ -6809,7 +6809,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha { ZigValue *optional_const_val = const_val->data.x_ptr.data.base_optional_payload.optional_val; assert(optional_const_val->type->id == ZigTypeIdOptional); - if (!type_has_bits(optional_const_val->type)) { + if (!type_has_bits(g, optional_const_val->type)) { // make this a null pointer ZigType *usize = g->builtin_types.entry_usize; const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), @@ -6847,7 +6847,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n Error err; ZigType *type_entry = const_val->type; - assert(type_has_bits(type_entry)); + assert(type_has_bits(g, type_entry)); check: switch (const_val->special) { case ConstValSpecialLazy: @@ -6900,12 +6900,12 @@ check: switch (const_val->special) { case ZigTypeIdOptional: { ZigType *child_type = type_entry->data.maybe.child_type; - if (!type_has_bits(child_type)) { - return LLVMConstInt(LLVMInt1Type(), const_val->data.x_optional ? 1 : 0, false); - } else if (get_codegen_ptr_type(type_entry) != nullptr) { + if (get_src_ptr_type(type_entry) != nullptr) { return gen_const_val_ptr(g, const_val, name); } else if (child_type->id == ZigTypeIdErrorSet) { return gen_const_val_err_set(g, const_val, name); + } else if (!type_has_bits(g, child_type)) { + return LLVMConstInt(LLVMInt1Type(), const_val->data.x_optional ? 1 : 0, false); } else { LLVMValueRef child_val; LLVMValueRef maybe_val; @@ -7128,7 +7128,7 @@ check: switch (const_val->special) { LLVMValueRef union_value_ref; bool make_unnamed_struct; ZigValue *payload_value = const_val->data.x_union.payload; - if (payload_value == nullptr || !type_has_bits(payload_value->type)) { + if (payload_value == nullptr || !type_has_bits(g, payload_value->type)) { if (type_entry->data.unionation.gen_tag_index == SIZE_MAX) return LLVMGetUndef(get_llvm_type(g, type_entry)); @@ -7205,13 +7205,13 @@ check: switch (const_val->special) { { ZigType *payload_type = type_entry->data.error_union.payload_type; ZigType *err_set_type = type_entry->data.error_union.err_set_type; - if (!type_has_bits(payload_type)) { - assert(type_has_bits(err_set_type)); + if (!type_has_bits(g, payload_type)) { + assert(type_has_bits(g, err_set_type)); ErrorTableEntry *err_set = const_val->data.x_err_union.error_set->data.x_err_set; uint64_t value = (err_set == nullptr) ? 0 : err_set->value; return LLVMConstInt(get_llvm_type(g, g->err_tag_type), value, false); - } else if (!type_has_bits(err_set_type)) { - assert(type_has_bits(payload_type)); + } else if (!type_has_bits(g, err_set_type)) { + assert(type_has_bits(g, payload_type)); return gen_const_val(g, const_val->data.x_err_union.payload, ""); } else { LLVMValueRef err_tag_value; @@ -7445,7 +7445,7 @@ static void do_code_gen(CodeGen *g) { continue; } - if (!type_has_bits(var->var_type)) + if (!type_has_bits(g, var->var_type)) continue; assert(var->decl_node); @@ -7544,7 +7544,7 @@ static void do_code_gen(CodeGen *g) { } else { if (want_sret) { g->cur_ret_ptr = LLVMGetParam(fn, 0); - } else if (type_has_bits(fn_type_id->return_type)) { + } else if (type_has_bits(g, fn_type_id->return_type)) { g->cur_ret_ptr = build_alloca(g, fn_type_id->return_type, "result", 0); // TODO add debug info variable for this } else { @@ -7609,7 +7609,7 @@ static void do_code_gen(CodeGen *g) { ZigType *child_type = ptr_type->data.pointer.child_type; if (type_resolve(g, child_type, ResolveStatusSizeKnown)) zig_unreachable(); - if (!type_has_bits(child_type)) + if (!type_has_bits(g, child_type)) continue; if (instruction->base.base.ref_count == 0) continue; @@ -7640,7 +7640,7 @@ static void do_code_gen(CodeGen *g) { for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) { ZigVar *var = fn_table_entry->variable_list.at(var_i); - if (!type_has_bits(var->var_type)) { + if (!type_has_bits(g, var->var_type)) { continue; } if (ir_get_var_is_comptime(var)) @@ -7667,7 +7667,7 @@ static void do_code_gen(CodeGen *g) { FnGenParamInfo *gen_info = &fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index]; assert(gen_info->gen_index != SIZE_MAX); - if (handle_is_ptr(var->var_type)) { + if (handle_is_ptr(g, var->var_type)) { if (gen_info->is_byval) { gen_type = var->var_type; } else { @@ -7739,7 +7739,7 @@ static void do_code_gen(CodeGen *g) { LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_resume_index, ""); g->cur_async_resume_index_ptr = resume_index_ptr; - if (type_has_bits(fn_type_id->return_type)) { + if (type_has_bits(g, fn_type_id->return_type)) { LLVMValueRef cur_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start, ""); g->cur_ret_ptr = LLVMBuildLoad(g->builder, cur_ret_ptr_ptr, ""); } @@ -9847,10 +9847,10 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu case ZigTypeIdOptional: { ZigType *child_type = type_entry->data.maybe.child_type; - if (!type_has_bits(child_type)) { + if (!type_has_bits(g, child_type)) { buf_init_from_str(out_buf, "bool"); return; - } else if (type_is_nonnull_ptr(child_type)) { + } else if (type_is_nonnull_ptr(g, child_type)) { return get_c_type(g, gen_h, child_type, out_buf); } else { zig_unreachable(); diff --git a/src/ir.cpp b/src/ir.cpp index 72e247b75a..42ad7d868c 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -860,7 +860,7 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte if (expected == actual) return true; - if (get_codegen_ptr_type(expected) != nullptr && get_codegen_ptr_type(actual) != nullptr) + if (get_src_ptr_type(expected) != nullptr && get_src_ptr_type(actual) != nullptr) return true; if (is_opt_err_set(expected) && is_opt_err_set(actual)) @@ -11399,7 +11399,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted result.id = ConstCastResultIdInvalid; return result; } - if (type_has_bits(wanted_type) == type_has_bits(actual_type) && + if (type_has_bits(g, wanted_type) == type_has_bits(g, actual_type) && actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && get_ptr_align(ira->codegen, actual_ptr_type) >= get_ptr_align(ira->codegen, wanted_ptr_type)) @@ -12532,7 +12532,7 @@ static IrInstGen *ir_const_move(IrAnalyze *ira, IrInst *old_instruction, ZigValu static IrInstGen *ir_resolve_cast(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, ZigType *wanted_type, CastOp cast_op) { - if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { + if (instr_is_comptime(value) || !type_has_bits(ira->codegen, wanted_type)) { IrInstGen *result = ir_const(ira, source_instr, wanted_type); if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, value->value, value->value->type, result->value, wanted_type)) @@ -12918,7 +12918,7 @@ static Error ir_resolve_const_val(CodeGen *codegen, IrExecutableGen *exec, AstNo case ConstValSpecialStatic: return ErrorNone; case ConstValSpecialRuntime: - if (!type_has_bits(val->type)) + if (!type_has_bits(codegen, val->type)) return ErrorNone; exec_add_error_node_gen(codegen, exec, source_node, @@ -13082,7 +13082,11 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstGen *type_value) { } static Error ir_validate_vector_elem_type(IrAnalyze *ira, AstNode *source_node, ZigType *elem_type) { - if (!is_valid_vector_elem_type(elem_type)) { + Error err; + bool is_valid; + if ((err = is_valid_vector_elem_type(ira->codegen, elem_type, &is_valid))) + return err; + if (!is_valid) { ir_add_error_node(ira, source_node, buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid", buf_ptr(&elem_type->name))); @@ -13198,7 +13202,7 @@ static IrInstGen *ir_analyze_optional_wrap(IrAnalyze *ira, IrInst* source_instr, return &const_instruction->base; } - if (result_loc == nullptr && handle_is_ptr(wanted_type)) { + if (result_loc == nullptr && handle_is_ptr(ira->codegen, wanted_type)) { result_loc = no_result_loc(); } IrInstGen *result_loc_inst = nullptr; @@ -13246,7 +13250,7 @@ static IrInstGen *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInst* source_ins } IrInstGen *result_loc_inst; - if (handle_is_ptr(wanted_type)) { + if (handle_is_ptr(ira->codegen, wanted_type)) { if (result_loc == nullptr) result_loc = no_result_loc(); result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); if (type_is_invalid(result_loc_inst->value->type) || @@ -13358,7 +13362,7 @@ static IrInstGen *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInst* source_instr, } IrInstGen *result_loc_inst; - if (handle_is_ptr(wanted_type)) { + if (handle_is_ptr(ira->codegen, wanted_type)) { if (result_loc == nullptr) result_loc = no_result_loc(); result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); if (type_is_invalid(result_loc_inst->value->type) || @@ -13385,7 +13389,8 @@ static IrInstGen *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInst *source_instr, IrInstGen *result = ir_const(ira, source_instr, wanted_type); result->value->special = ConstValSpecialStatic; - if (get_codegen_ptr_type(wanted_type) != nullptr) { + + if (get_src_ptr_type(wanted_type) != nullptr) { result->value->data.x_ptr.special = ConstPtrSpecialNull; } else if (is_opt_err_set(wanted_type)) { result->value->data.x_err_set = nullptr; @@ -13434,7 +13439,7 @@ static IrInstGen *ir_get_ref2(IrAnalyze *ira, IrInst* source_instruction, IrInst return ira->codegen->invalid_inst_gen; IrInstGen *result_loc; - if (type_has_bits(ptr_type) && !handle_is_ptr(elem_type)) { + if (type_has_bits(ira->codegen, ptr_type) && !handle_is_ptr(ira->codegen, elem_type)) { result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), elem_type, nullptr, true, true); } else { result_loc = nullptr; @@ -13679,9 +13684,9 @@ static IrInstGen *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInst* source_ins // If the destination integer type has no bits, then we can emit a comptime // zero. However, we still want to emit a runtime safety check to make sure // the target is zero. - if (!type_has_bits(wanted_type)) { + if (!type_has_bits(ira->codegen, wanted_type)) { assert(wanted_type->id == ZigTypeIdInt); - assert(type_has_bits(target->value->type)); + assert(type_has_bits(ira->codegen, target->value->type)); ir_build_assert_zero(ira, source_instr, target); IrInstGen *result = ir_const_unsigned(ira, source_instr, 0); result->value->type = wanted_type; @@ -15038,7 +15043,7 @@ static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrIns } IrInstGen *result_loc_inst; - if (ptr_type->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { + if (ptr_type->data.pointer.host_int_bytes != 0 && handle_is_ptr(ira->codegen, child_type)) { if (result_loc == nullptr) result_loc = no_result_loc(); result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, true, true); if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { @@ -15298,7 +15303,7 @@ static IrInstGen *ir_analyze_instruction_return(IrAnalyze *ira, IrInstSrcReturn } if (!instr_is_comptime(operand) && ira->explicit_return_type != nullptr && - handle_is_ptr(ira->explicit_return_type)) + handle_is_ptr(ira->codegen, ira->explicit_return_type)) { // result location mechanism took care of it. IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, nullptr); @@ -15387,7 +15392,7 @@ static bool resolve_cmp_op_id(IrBinOp op_id, Cmp cmp) { static bool optional_value_is_null(ZigValue *val) { assert(val->special == ConstValSpecialStatic); - if (get_codegen_ptr_type(val->type) != nullptr) { + if (get_src_ptr_type(val->type) != nullptr) { if (val->data.x_ptr.special == ConstPtrSpecialNull) { return true; } else if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { @@ -15406,7 +15411,7 @@ static void set_optional_value_to_null(ZigValue *val) { assert(val->special == ConstValSpecialStatic); if (val->type->id == ZigTypeIdNull) return; // nothing to do assert(val->type->id == ZigTypeIdOptional); - if (get_codegen_ptr_type(val->type) != nullptr) { + if (get_src_ptr_type(val->type) != nullptr) { val->data.x_ptr.special = ConstPtrSpecialNull; } else if (is_opt_err_set(val->type)) { val->data.x_err_set = nullptr; @@ -16244,7 +16249,7 @@ static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_i operator_allowed = false; break; case ZigTypeIdOptional: - operator_allowed = is_equality_cmp && get_codegen_ptr_type(resolved_type) != nullptr; + operator_allowed = is_equality_cmp && get_src_ptr_type(resolved_type) != nullptr; break; } if (!operator_allowed) { @@ -17894,7 +17899,7 @@ static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira, if (!exec_has_err_ret_trace(ira->codegen, ira->old_irb.exec)) { IrInstGen *result = ir_const(ira, &instruction->base.base, optional_type); ZigValue *out_val = result->value; - assert(get_codegen_ptr_type(optional_type) != nullptr); + assert(get_src_ptr_type(optional_type) != nullptr); out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; out_val->data.x_ptr.data.hard_coded_addr.addr = 0; return result; @@ -18283,7 +18288,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { return ira->codegen->invalid_inst_gen; } - if (!type_has_bits(value_type)) { + if (!type_has_bits(ira->codegen, value_type)) { parent_ptr_align = 0; } // If we're casting from a sentinel-terminated array to a non-sentinel-terminated array, @@ -18328,7 +18333,10 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i if (type_is_invalid(dest_type)) return ira->codegen->invalid_inst_gen; - if (get_codegen_ptr_type(dest_type) != nullptr) { + ZigType *dest_cg_ptr_type; + if ((err = get_codegen_ptr_type(ira->codegen, dest_type, &dest_cg_ptr_type))) + return ira->codegen->invalid_inst_gen; + if (dest_cg_ptr_type != nullptr) { ir_add_error(ira, &result_loc->source_instruction->base, buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); return ira->codegen->invalid_inst_gen; @@ -18340,7 +18348,10 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i return ira->codegen->invalid_inst_gen; } - if (get_codegen_ptr_type(value_type) != nullptr) { + ZigType *value_cg_ptr_type; + if ((err = get_codegen_ptr_type(ira->codegen, value_type, &value_cg_ptr_type))) + return ira->codegen->invalid_inst_gen; + if (value_cg_ptr_type != nullptr) { ir_add_error(ira, suspend_source_instr, buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&value_type->name))); return ira->codegen->invalid_inst_gen; @@ -18400,7 +18411,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i } } uint64_t parent_ptr_align = 0; - if (type_has_bits(value_type)) parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); + if (type_has_bits(ira->codegen, value_type)) parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); @@ -19118,7 +19129,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, } IrInstGen *first_arg; - if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) { + if (!first_arg_known_bare && handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) { first_arg = first_arg_ptr; } else { first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); @@ -19247,7 +19258,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, } IrInstGen *first_arg; - if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) { + if (!first_arg_known_bare && handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) { first_arg = first_arg_ptr; } else { first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); @@ -19366,7 +19377,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, } IrInstGen *result_loc; - if (handle_is_ptr(impl_fn_type_id->return_type)) { + if (handle_is_ptr(ira->codegen, impl_fn_type_id->return_type)) { result_loc = ir_resolve_result(ira, source_instr, call_result_loc, impl_fn_type_id->return_type, nullptr, true, false); if (result_loc != nullptr) { @@ -19383,7 +19394,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, if (res_child_type == ira->codegen->builtin_types.entry_var) { res_child_type = impl_fn_type_id->return_type; } - if (!handle_is_ptr(res_child_type)) { + if (!handle_is_ptr(ira->codegen, res_child_type)) { ir_reset_result(call_result_loc); result_loc = nullptr; } @@ -19435,7 +19446,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, IrInstGen *first_arg; if (param_type->id == ZigTypeIdPointer && - handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) + handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) { first_arg = first_arg_ptr; } else { @@ -19504,7 +19515,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, } IrInstGen *result_loc; - if (handle_is_ptr(return_type)) { + if (handle_is_ptr(ira->codegen, return_type)) { result_loc = ir_resolve_result(ira, source_instr, call_result_loc, return_type, nullptr, true, false); if (result_loc != nullptr) { @@ -19521,7 +19532,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, if (res_child_type == ira->codegen->builtin_types.entry_var) { res_child_type = return_type; } - if (!handle_is_ptr(res_child_type)) { + if (!handle_is_ptr(ira->codegen, res_child_type)) { ir_reset_result(call_result_loc); result_loc = nullptr; } @@ -23346,7 +23357,7 @@ static TypeStructField *validate_byte_offset(IrAnalyze *ira, return nullptr; } - if (!type_has_bits(field->type_entry)) { + if (!type_has_bits(ira->codegen, field->type_entry)) { ir_add_error(ira, &field_name_value->base, buf_sprintf("zero-bit field '%s' in struct '%s' has no offset", buf_ptr(field_name), buf_ptr(&container_type->name))); @@ -24264,7 +24275,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy return ErrorSemanticAnalyzeFail; if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) return err; - if (!type_has_bits(struct_field->type_entry)) { + if (!type_has_bits(ira->codegen, struct_field->type_entry)) { inner_fields[1]->data.x_optional = nullptr; } else { size_t byte_offset = struct_field->offset; @@ -25077,7 +25088,7 @@ static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxch ZigType *result_type = get_optional_type(ira->codegen, operand_type); IrInstGen *result_loc; - if (handle_is_ptr(result_type)) { + if (handle_is_ptr(ira->codegen, result_type)) { result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, result_type, nullptr, true, true); if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { @@ -25396,8 +25407,11 @@ static IrInstGen *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstSrcVe static IrInstGen *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInst* source_instr, ZigType *scalar_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask) { + Error err; ir_assert(source_instr && scalar_type && a && b && mask, source_instr); - ir_assert(is_valid_vector_elem_type(scalar_type), source_instr); + + if ((err = ir_validate_vector_elem_type(ira, source_instr->source_node, scalar_type))) + return ira->codegen->invalid_inst_gen; uint32_t len_mask; if (mask->value->type->id == ZigTypeIdVector) { @@ -27364,7 +27378,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) return ira->codegen->invalid_inst_gen; - if (type_has_bits(dest_type) && !type_has_bits(src_type) && safety_check_on) { + if (type_has_bits(ira->codegen, dest_type) && !type_has_bits(ira->codegen, src_type) && safety_check_on) { ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("'%s' and '%s' do not have the same in-memory representation", buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); @@ -27423,7 +27437,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn // Keep the bigger alignment, it can only help- // unless the target is zero bits. - if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { + if (src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { result = ir_align_cast(ira, result, src_align_bytes, false); } @@ -27444,7 +27458,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn // Keep the bigger alignment, it can only help- // unless the target is zero bits. IrInstGen *result; - if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { + if (src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); if (type_is_invalid(result->value->type)) return ira->codegen->invalid_inst_gen; @@ -27802,9 +27816,7 @@ static IrInstGen *ir_analyze_bit_cast(IrAnalyze *ira, IrInst* source_instr, IrIn Error err; ZigType *src_type = value->value->type; - ir_assert(get_codegen_ptr_type(src_type) == nullptr, source_instr); ir_assert(type_can_bit_cast(src_type), source_instr); - ir_assert(get_codegen_ptr_type(dest_type) == nullptr, source_instr); ir_assert(type_can_bit_cast(dest_type), source_instr); if (dest_type->id == ZigTypeIdEnum) { @@ -27863,7 +27875,7 @@ static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, Ir Error err; ir_assert(get_src_ptr_type(ptr_type) != nullptr, source_instr); - ir_assert(type_has_bits(ptr_type), source_instr); + ir_assert(type_has_bits(ira->codegen, ptr_type), source_instr); IrInstGen *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); if (type_is_invalid(casted_int->value->type)) @@ -27981,7 +27993,7 @@ static IrInstGen *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstSrcPtr if (!val) return ira->codegen->invalid_inst_gen; - // Since we've already run this type trough get_codegen_ptr_type it is + // Since we've already run this type trough get_src_ptr_type it is // safe to access the x_ptr fields if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { IrInstGen *result = ir_const(ira, &instruction->base.base, usize); @@ -28232,10 +28244,17 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) { max_atomic_bits, (uint32_t) operand_type->data.floating.bit_count)); return ira->codegen->builtin_types.entry_invalid; } - } else if (get_codegen_ptr_type(operand_type) == nullptr) { - ir_add_error(ira, &op->base, - buf_sprintf("expected integer, float, enum or pointer type, found '%s'", buf_ptr(&operand_type->name))); - return ira->codegen->builtin_types.entry_invalid; + } else { + Error err; + ZigType *operand_ptr_type; + if ((err = get_codegen_ptr_type(ira->codegen, operand_type, &operand_ptr_type))) + return ira->codegen->builtin_types.entry_invalid; + if (operand_ptr_type == nullptr) { + ir_add_error(ira, &op->base, + buf_sprintf("expected integer, float, enum or pointer type, found '%s'", + buf_ptr(&operand_type->name))); + return ira->codegen->builtin_types.entry_invalid; + } } return operand_type; @@ -28666,15 +28685,19 @@ static IrInstGen *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstSrcBswap *i if (type_is_invalid(uncasted_op->value->type)) return ira->codegen->invalid_inst_gen; - uint32_t vector_len; // UINT32_MAX means not a vector - if (uncasted_op->value->type->id == ZigTypeIdArray && - is_valid_vector_elem_type(uncasted_op->value->type->data.array.child_type)) - { - vector_len = uncasted_op->value->type->data.array.len; + uint32_t vector_len = UINT32_MAX; // means not a vector + if (uncasted_op->value->type->id == ZigTypeIdArray) { + bool can_be_vec_elem; + if ((err = is_valid_vector_elem_type(ira->codegen, uncasted_op->value->type->data.array.child_type, + &can_be_vec_elem))) + { + return ira->codegen->invalid_inst_gen; + } + if (can_be_vec_elem) { + vector_len = uncasted_op->value->type->data.array.len; + } } else if (uncasted_op->value->type->id == ZigTypeIdVector) { vector_len = uncasted_op->value->type->data.vector.len; - } else { - vector_len = UINT32_MAX; } bool is_vector = (vector_len != UINT32_MAX); @@ -29075,7 +29098,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i } IrInstGen *result_loc; - if (type_has_bits(result_type)) { + if (type_has_bits(ira->codegen, result_type)) { result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, result_type, nullptr, true, true); if (result_loc != nullptr && @@ -29125,7 +29148,7 @@ static IrInstGen *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstSrcSp if (type_is_invalid(operand->value->type)) return ira->codegen->invalid_inst_gen; - if (!type_has_bits(operand->value->type)) + if (!type_has_bits(ira->codegen, operand->value->type)) return ir_const_void(ira, &instruction->base.base); switch (instruction->spill_id) { @@ -29145,7 +29168,7 @@ static IrInstGen *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstSrcSpil return ira->codegen->invalid_inst_gen; if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope) || - !type_has_bits(operand->value->type) || + !type_has_bits(ira->codegen, operand->value->type) || instr_is_comptime(operand)) { return operand; @@ -30188,7 +30211,7 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { if (align_bytes != 0) { if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) return err; - if (!type_has_bits(elem_type)) + if (!type_has_bits(ira->codegen, elem_type)) align_bytes = 0; } bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC; diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index d2267a3753..0304ddfa9c 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -786,3 +786,10 @@ test "cast between C pointer with different but compatible types" { }; S.doTheTest(); } + +var global_struct: struct { f0: usize } = undefined; + +test "assignment to optional pointer result loc" { + var foo: struct { ptr: ?*c_void } = .{ .ptr = &global_struct }; + expect(foo.ptr.? == @ptrCast(*c_void, &global_struct)); +}