Commit f247a90541
Changed files (5)
test
stage1
behavior
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, "<TODO dump value>\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, "<!invalid ptr!>\n");
+ return;
+ case ConstPtrSpecialNull:
+ fprintf(stderr, "<null>\n");
+ return;
+ case ConstPtrSpecialRef:
+ fprintf(stderr, "<ref\n");
+ dump_value_indent(val->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, "<struct %p field %zu\n", struct_val, field_index);
+ if (struct_val != nullptr) {
+ ZigValue *field_val = struct_val->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, "<optional %p payload\n", optional_val);
+ if (optional_val != nullptr) {
+ dump_value_indent(optional_val, indent + 1);
+ }
+ break;
+ }
+ default:
+ fprintf(stderr, "TODO dump more pointer things\n");
+ }
+ for (int i = 0; i < indent; i += 1) {
+ fprintf(stderr, " ");
+ }
+ 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, "<!invalid ptr!>\n");
- return;
- case ConstPtrSpecialRef:
- fprintf(stderr, "<ref\n");
- dump_value_indent(val->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, "<struct %p field %zu\n", struct_val, field_index);
- if (struct_val != nullptr) {
- ZigValue *field_val = struct_val->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, "<optional %p payload\n", optional_val);
- if (optional_val != nullptr) {
- dump_value_indent(optional_val, indent + 1);
- }
- break;
- }
- default:
- fprintf(stderr, "TODO dump more pointer things\n");
- }
- for (int i = 0; i < indent; i += 1) {
- fprintf(stderr, " ");
- }
- 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:
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);
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();
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;
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));
+}