aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-09-14 18:56:30 -0400
committerAndrew Kelley <superjoe30@gmail.com>2018-09-14 19:08:59 -0400
commit3f776af3fa58b47d15a81b17c15e5b0e1c5ccf28 (patch)
treebdcbd8dcf83e452a6ef10de8e74899494fa4c21c /src/ir.cpp
parent639c3811288b65173b3d9706b8e2001ee2419233 (diff)
downloadzig-3f776af3fa58b47d15a81b17c15e5b0e1c5ccf28.tar.gz
zig-3f776af3fa58b47d15a81b17c15e5b0e1c5ccf28.zip
fix alignment of structs
closes #1248 closes #1052 closes #1154
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp376
1 files changed, 257 insertions, 119 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index fd23992a9e..ce044aa0f3 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -40,6 +40,7 @@ struct IrAnalyze {
enum ConstCastResultId {
ConstCastResultIdOk,
+ ConstCastResultIdInvalid,
ConstCastResultIdErrSet,
ConstCastResultIdErrSetGlobal,
ConstCastResultIdPointerChild,
@@ -7490,8 +7491,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
if (type_has_bits(return_type)) {
IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node,
get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8,
- false, false, PtrLenUnknown, get_abi_alignment(irb->codegen, irb->codegen->builtin_types.entry_u8),
- 0, 0));
+ false, false, PtrLenUnknown, 0, 0, 0));
IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);
IrInstruction *result_ptr_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len, result_ptr);
IrInstruction *return_value_ptr_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len,
@@ -7544,8 +7544,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle);
IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node,
get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8,
- false, false, PtrLenUnknown, get_abi_alignment(irb->codegen, irb->codegen->builtin_types.entry_u8),
- 0, 0));
+ false, false, PtrLenUnknown, 0, 0, 0));
IrInstruction *coro_mem_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len, coro_mem_ptr_maybe);
IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);
IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);
@@ -8516,6 +8515,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
ConstCastOnly result = {};
result.id = ConstCastResultIdOk;
+ Error err;
+
if (wanted_type == actual_type)
return result;
@@ -8528,6 +8529,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
{
ConstCastOnly child = types_match_const_cast_only(ira,
wanted_type->data.maybe.child_type, actual_type, source_node, wanted_is_mutable);
+ if (child.id == ConstCastResultIdInvalid)
+ return child;
if (child.id != ConstCastResultIdOk) {
result.id = ConstCastResultIdNullWrapPtr;
result.data.null_wrap_ptr_child = allocate_nonzero<ConstCastOnly>(1);
@@ -8544,7 +8547,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
(!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&
(!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile))
{
- assert(actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment);
return result;
}
@@ -8552,6 +8554,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer) {
ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const);
+ if (child.id == ConstCastResultIdInvalid)
+ return child;
if (child.id != ConstCastResultIdOk) {
result.id = ConstCastResultIdPointerChild;
result.data.pointer_mismatch = allocate_nonzero<ConstCastPointerMismatch>(1);
@@ -8560,12 +8564,20 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
result.data.pointer_mismatch->actual_child = actual_type->data.pointer.child_type;
return result;
}
+ if ((err = type_resolve(g, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
+ result.id = ConstCastResultIdInvalid;
+ return result;
+ }
+ if ((err = type_resolve(g, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
+ result.id = ConstCastResultIdInvalid;
+ return result;
+ }
if ((actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) &&
(!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&
(!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) &&
actual_type->data.pointer.bit_offset == wanted_type->data.pointer.bit_offset &&
actual_type->data.pointer.unaligned_bit_count == wanted_type->data.pointer.unaligned_bit_count &&
- actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment)
+ get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type))
{
return result;
}
@@ -8575,14 +8587,24 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
if (is_slice(wanted_type) && is_slice(actual_type)) {
ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry;
ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
+ if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
+ result.id = ConstCastResultIdInvalid;
+ return result;
+ }
+ if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
+ result.id = ConstCastResultIdInvalid;
+ return result;
+ }
if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) &&
(!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) &&
actual_ptr_type->data.pointer.bit_offset == wanted_ptr_type->data.pointer.bit_offset &&
actual_ptr_type->data.pointer.unaligned_bit_count == wanted_ptr_type->data.pointer.unaligned_bit_count &&
- actual_ptr_type->data.pointer.alignment >= wanted_ptr_type->data.pointer.alignment)
+ get_ptr_align(g, actual_ptr_type) >= get_ptr_align(g, wanted_ptr_type))
{
ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
+ if (child.id == ConstCastResultIdInvalid)
+ return child;
if (child.id != ConstCastResultIdOk) {
result.id = ConstCastResultIdSliceChild;
result.data.slice_mismatch = allocate_nonzero<ConstCastSliceMismatch>(1);
@@ -8598,6 +8620,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
if (wanted_type->id == ZigTypeIdOptional && actual_type->id == ZigTypeIdOptional) {
ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type,
actual_type->data.maybe.child_type, source_node, wanted_is_mutable);
+ if (child.id == ConstCastResultIdInvalid)
+ return child;
if (child.id != ConstCastResultIdOk) {
result.id = ConstCastResultIdOptionalChild;
result.data.optional = allocate_nonzero<ConstCastOptionalMismatch>(1);
@@ -8612,6 +8636,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id == ZigTypeIdErrorUnion) {
ConstCastOnly payload_child = types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type,
actual_type->data.error_union.payload_type, source_node, wanted_is_mutable);
+ if (payload_child.id == ConstCastResultIdInvalid)
+ return payload_child;
if (payload_child.id != ConstCastResultIdOk) {
result.id = ConstCastResultIdErrorUnionPayload;
result.data.error_union_payload = allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1);
@@ -8622,6 +8648,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
}
ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type,
actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable);
+ if (error_set_child.id == ConstCastResultIdInvalid)
+ return error_set_child;
if (error_set_child.id != ConstCastResultIdOk) {
result.id = ConstCastResultIdErrorUnionErrorSet;
result.data.error_union_error_set = allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1);
@@ -8709,6 +8737,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
{
ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.fn.fn_type_id.return_type,
actual_type->data.fn.fn_type_id.return_type, source_node, false);
+ if (child.id == ConstCastResultIdInvalid)
+ return child;
if (child.id != ConstCastResultIdOk) {
result.id = ConstCastResultIdFnReturnType;
result.data.return_type = allocate_nonzero<ConstCastOnly>(1);
@@ -8721,6 +8751,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
actual_type->data.fn.fn_type_id.async_allocator_type,
wanted_type->data.fn.fn_type_id.async_allocator_type,
source_node, false);
+ if (child.id == ConstCastResultIdInvalid)
+ return child;
if (child.id != ConstCastResultIdOk) {
result.id = ConstCastResultIdAsyncAllocatorType;
result.data.async_allocator_type = allocate_nonzero<ConstCastOnly>(1);
@@ -8745,6 +8777,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
ConstCastOnly arg_child = types_match_const_cast_only(ira, actual_param_info->type,
expected_param_info->type, source_node, false);
+ if (arg_child.id == ConstCastResultIdInvalid)
+ return arg_child;
if (arg_child.id != ConstCastResultIdOk) {
result.id = ConstCastResultIdFnArg;
result.data.fn_arg.arg_index = i;
@@ -9238,7 +9272,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdUnion &&
(cur_type->data.unionation.decl_node->data.container_decl.auto_enum || cur_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr))
{
- if ((err = type_ensure_zero_bits_known(ira->codegen, cur_type)))
+ if ((err = type_resolve(ira->codegen, cur_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
if (cur_type->data.unionation.tag_type == prev_type) {
continue;
@@ -9248,7 +9282,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdUnion &&
(prev_type->data.unionation.decl_node->data.container_decl.auto_enum || prev_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr))
{
- if ((err = type_ensure_zero_bits_known(ira->codegen, prev_type)))
+ if ((err = type_resolve(ira->codegen, prev_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
if (prev_type->data.unionation.tag_type == cur_type) {
prev_inst = cur_inst;
@@ -9274,8 +9308,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
ZigType *ptr_type = get_pointer_to_type_extra(
ira->codegen, prev_inst->value.type->data.array.child_type,
true, false, PtrLenUnknown,
- get_abi_alignment(ira->codegen, prev_inst->value.type->data.array.child_type),
- 0, 0);
+ 0, 0, 0);
ZigType *slice_type = get_slice_type(ira->codegen, ptr_type);
if (err_set_type != nullptr) {
return get_error_union_type(ira->codegen, err_set_type, slice_type);
@@ -9472,7 +9505,16 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira,
IrInstruction *value, ZigType *wanted_type)
{
assert(value->value.type->id == ZigTypeIdPointer);
- wanted_type = adjust_ptr_align(ira->codegen, wanted_type, value->value.type->data.pointer.alignment);
+
+ Error err;
+
+ if ((err = type_resolve(ira->codegen, value->value.type->data.pointer.child_type,
+ ResolveStatusAlignmentKnown)))
+ {
+ return ira->codegen->invalid_instruction;
+ }
+
+ wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value.type));
if (instr_is_comptime(value)) {
ConstExprValue *pointee = ir_const_ptr_pointee(ira, &value->value, source_instr->source_node);
@@ -9500,7 +9542,15 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira,
static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,
IrInstruction *value, ZigType *wanted_type)
{
- wanted_type = adjust_slice_align(ira->codegen, wanted_type, value->value.type->data.pointer.alignment);
+ Error err;
+
+ if ((err = type_resolve(ira->codegen, value->value.type->data.pointer.child_type,
+ ResolveStatusAlignmentKnown)))
+ {
+ return ira->codegen->invalid_instruction;
+ }
+
+ wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value.type));
if (instr_is_comptime(value)) {
ConstExprValue *pointee = ir_const_ptr_pointee(ira, &value->value, source_instr->source_node);
@@ -9687,8 +9737,7 @@ static ZigType *ir_analyze_const_ptr(IrAnalyze *ira, IrInstruction *instruction,
ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile)
{
IrInstruction *const_instr = ir_get_const_ptr(ira, instruction, pointee,
- pointee_type, ptr_mut, ptr_is_const, ptr_is_volatile,
- get_abi_alignment(ira->codegen, pointee_type));
+ pointee_type, ptr_mut, ptr_is_const, ptr_is_volatile, 0);
ir_link_new_instruction(const_instr, instruction);
return const_instr->value.type;
}
@@ -10005,20 +10054,24 @@ static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *so
static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value,
bool is_const, bool is_volatile)
{
+ Error err;
+
if (type_is_invalid(value->value.type))
return ira->codegen->invalid_instruction;
+ if ((err = type_resolve(ira->codegen, value->value.type, ResolveStatusZeroBitsKnown)))
+ return ira->codegen->invalid_instruction;
+
if (instr_is_comptime(value)) {
ConstExprValue *val = ir_resolve_const(ira, value, UndefOk);
if (!val)
return ira->codegen->invalid_instruction;
return ir_get_const_ptr(ira, source_instruction, val, value->value.type,
- ConstPtrMutComptimeConst, is_const, is_volatile,
- get_abi_alignment(ira->codegen, value->value.type));
+ ConstPtrMutComptimeConst, is_const, is_volatile, 0);
}
ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type,
- is_const, is_volatile, PtrLenSingle, get_abi_alignment(ira->codegen, value->value.type), 0, 0);
+ is_const, is_volatile, PtrLenSingle, 0, 0, 0);
IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope,
source_instruction->source_node, value, is_const, is_volatile);
new_instruction->value.type = ptr_type;
@@ -10185,9 +10238,9 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so
return ira->codegen->invalid_instruction;
TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag);
assert(union_field != nullptr);
- if ((err = type_ensure_zero_bits_known(ira->codegen, union_field->type_entry)))
+ if ((err = type_resolve(ira->codegen, union_field->type_entry, ResolveStatusZeroBitsKnown)))
return ira->codegen->invalid_instruction;
- if (!union_field->type_entry->zero_bits) {
+ if (type_has_bits(union_field->type_entry)) {
AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(
union_field->enum_field->decl_index);
ErrorMsg *msg = ir_add_error(ira, source_instr,
@@ -10490,7 +10543,10 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou
ZigType *wanted_type)
{
assert(wanted_type->id == ZigTypeIdPointer);
- wanted_type = adjust_ptr_align(ira->codegen, wanted_type, target->value.type->data.pointer.alignment);
+ Error err;
+ if ((err = type_resolve(ira->codegen, target->value.type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
+ return ira->codegen->invalid_instruction;
+ wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, target->value.type));
ZigType *array_type = wanted_type->data.pointer.child_type;
assert(array_type->id == ZigTypeIdArray);
assert(array_type->data.array.len == 1);
@@ -10537,6 +10593,8 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
switch (cast_result->id) {
case ConstCastResultIdOk:
zig_unreachable();
+ case ConstCastResultIdInvalid:
+ zig_unreachable();
case ConstCastResultIdOptionalChild: {
ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node,
buf_sprintf("optional type child '%s' cannot cast into optional type child '%s'",
@@ -10636,6 +10694,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
// perfect match or non-const to const
ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type,
source_node, false);
+ if (const_cast_result.id == ConstCastResultIdInvalid)
+ return ira->codegen->invalid_instruction;
if (const_cast_result.id == ConstCastResultIdOk) {
return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
}
@@ -10751,13 +10811,19 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
wanted_type->data.pointer.ptr_len == PtrLenUnknown &&
actual_type->id == ZigTypeIdPointer &&
actual_type->data.pointer.ptr_len == PtrLenSingle &&
- actual_type->data.pointer.child_type->id == ZigTypeIdArray &&
- actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment &&
- types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
- actual_type->data.pointer.child_type->data.array.child_type, source_node,
- !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
+ actual_type->data.pointer.child_type->id == ZigTypeIdArray)
{
- return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type);
+ if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
+ return ira->codegen->invalid_instruction;
+ if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
+ return ira->codegen->invalid_instruction;
+ if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) &&
+ types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
+ actual_type->data.pointer.child_type->data.array.child_type, source_node,
+ !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
+ {
+ return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type);
+ }
}
// *[N]T to []T
@@ -10811,16 +10877,23 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
wanted_child_type->data.pointer.ptr_len == PtrLenUnknown &&
actual_type->id == ZigTypeIdPointer &&
actual_type->data.pointer.ptr_len == PtrLenSingle &&
- actual_type->data.pointer.child_type->id == ZigTypeIdArray &&
- actual_type->data.pointer.alignment >= wanted_child_type->data.pointer.alignment &&
- types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type,
- actual_type->data.pointer.child_type->data.array.child_type, source_node,
- !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk)
+ actual_type->data.pointer.child_type->id == ZigTypeIdArray)
{
- IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_child_type);
- if (type_is_invalid(cast1->value.type))
+ if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
return ira->codegen->invalid_instruction;
- return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type);
+ if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown)))
+ return ira->codegen->invalid_instruction;
+ if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) &&
+ types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type,
+ actual_type->data.pointer.child_type->data.array.child_type, source_node,
+ !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk)
+ {
+ IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value,
+ wanted_child_type);
+ if (type_is_invalid(cast1->value.type))
+ return ira->codegen->invalid_instruction;
+ return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type);
+ }
}
}
@@ -10963,7 +11036,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
// cast from union to the enum type of the union
if (actual_type->id == ZigTypeIdUnion && wanted_type->id == ZigTypeIdEnum) {
- if ((err = type_ensure_zero_bits_known(ira->codegen, actual_type)))
+ if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->invalid_instruction;
if (actual_type->data.unionation.tag_type == wanted_type) {
@@ -10976,7 +11049,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
(wanted_type->data.unionation.decl_node->data.container_decl.auto_enum ||
wanted_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr))
{
- if ((err = type_ensure_zero_bits_known(ira->codegen, wanted_type)))
+ if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->invalid_instruction;
if (wanted_type->data.unionation.tag_type == actual_type) {
@@ -10990,7 +11063,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
if (union_type->data.unionation.decl_node->data.container_decl.auto_enum ||
union_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)
{
- if ((err = type_ensure_zero_bits_known(ira->codegen, union_type)))
+ if ((err = type_resolve(ira->codegen, union_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->invalid_instruction;
if (union_type->data.unionation.tag_type == actual_type) {
@@ -11017,14 +11090,24 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
actual_type->data.pointer.child_type, source_node,
!wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
{
- if (wanted_type->data.pointer.alignment > actual_type->data.pointer.alignment) {
+ if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type,
+ ResolveStatusAlignmentKnown)))
+ {
+ return ira->codegen->invalid_instruction;
+ }
+ if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type,
+ ResolveStatusAlignmentKnown)))
+ {
+ return ira->codegen->invalid_instruction;
+ }
+ uint32_t wanted_align = get_ptr_align(ira->codegen, wanted_type);
+ uint32_t actual_align = get_ptr_align(ira->codegen, actual_type);
+ if (wanted_align > actual_align) {
ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment"));
add_error_note(ira->codegen, msg, value->source_node,
- buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&actual_type->name),
- actual_type->data.pointer.alignment));
+ buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&actual_type->name), actual_align));
add_error_note(ira->codegen, msg, source_instr->source_node,
- buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&wanted_type->name),
- wanted_type->data.pointer.alignment));
+ buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&wanted_type->name), wanted_align));
return ira->codegen->invalid_instruction;
}
return ir_analyze_ptr_to_array(ira, source_instr, value, wanted_type);
@@ -11036,7 +11119,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
{
- if ((err = type_ensure_zero_bits_known(ira->codegen, actual_type))) {
+ if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) {
return ira->codegen->invalid_instruction;
}
if (!type_has_bits(actual_type)) {
@@ -11282,8 +11365,7 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {
return nullptr;
ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
- true, false, PtrLenUnknown,
- get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 0, 0);
+ true, false, PtrLenUnknown, 0, 0, 0);
ZigType *str_type = get_slice_type(ira->codegen, ptr_type);
IrInstruction *casted_value = ir_implicit_cast(ira, value, str_type);
if (type_is_invalid(casted_value->value.type))
@@ -11573,8 +11655,6 @@ static ZigType *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op
ZigType *resolved_type = ir_resolve_peer_types(ira, source_node, nullptr, instructions, 2);
if (type_is_invalid(resolved_type))
return resolved_type;
- if ((err = type_ensure_zero_bits_known(ira->codegen, resolved_type)))
- return resolved_type;
bool operator_allowed;
switch (resolved_type->id) {
@@ -11630,6 +11710,9 @@ static ZigType *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op
if (casted_op2 == ira->codegen->invalid_instruction)
return ira->codegen->builtin_types.entry_invalid;
+ if ((err = type_resolve(ira->codegen, resolved_type, ResolveStatusZeroBitsKnown)))
+ return resolved_type;
+
bool one_possible_value = !type_requires_comptime(resolved_type) && !type_has_bits(resolved_type);
if (one_possible_value || (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2))) {
ConstExprValue *op1_val = one_possible_value ? &casted_op1->value : ir_resolve_const(ira, casted_op1, UndefBad);
@@ -12316,7 +12399,7 @@ static ZigType *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruc
out_array_val = out_val;
} else if (is_slice(op1_type) || is_slice(op2_type)) {
ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, child_type,
- true, false, PtrLenUnknown, get_abi_alignment(ira->codegen, child_type), 0, 0);
+ true, false, PtrLenUnknown, 0, 0, 0);
result_type = get_slice_type(ira->codegen, ptr_type);
out_array_val = create_const_vals(1);
out_array_val->special = ConstValSpecialStatic;
@@ -12337,8 +12420,7 @@ static ZigType *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruc
new_len += 1; // null byte
// TODO make this `[*]null T` instead of `[*]T`
- result_type = get_pointer_to_type_extra(ira->codegen, child_type, true, false,
- PtrLenUnknown, get_abi_alignment(ira->codegen, child_type), 0, 0);
+ result_type = get_pointer_to_type_extra(ira->codegen, child_type, true, false, PtrLenUnknown, 0, 0, 0);
out_array_val = create_const_vals(1);
out_array_val->special = ConstValSpecialStatic;
@@ -12563,7 +12645,7 @@ static ZigType *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDec
if (type_is_invalid(result_type)) {
result_type = ira->codegen->builtin_types.entry_invalid;
} else {
- if ((err = type_ensure_zero_bits_known(ira->codegen, result_type))) {
+ if ((err = type_resolve(ira->codegen, result_type, ResolveStatusZeroBitsKnown))) {
result_type = ira->codegen->builtin_types.entry_invalid;
}
}
@@ -12631,6 +12713,11 @@ static ZigType *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDec
}
if (decl_var_instruction->align_value == nullptr) {
+ if ((err = type_resolve(ira->codegen, result_type, ResolveStatusAlignmentKnown))) {
+ var->value->type = ira->codegen->builtin_types.entry_invalid;
+ decl_var_instruction->base.other = &decl_var_instruction->base;
+ return ira->codegen->builtin_types.entry_void;
+ }
var->align_bytes = get_abi_alignment(ira->codegen, result_type);
} else {
if (!ir_resolve_align(ira, decl_var_instruction->align_value->other, &var->align_bytes)) {
@@ -13100,7 +13187,6 @@ static ZigVar *get_fn_var_by_index(ZigFn *fn_entry, size_t index) {
static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
ZigVar *var)
{
- Error err;
while (var->next_var != nullptr) {
var = var->next_var;
}
@@ -13158,8 +13244,6 @@ no_mem_slot:
instruction->scope, instruction->source_node, var);
var_ptr_instruction->value.type = get_pointer_to_type_extra(ira->codegen, var->value->type,
var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0);
- if ((err = type_ensure_zero_bits_known(ira->codegen, var->value->type)))
- return ira->codegen->invalid_instruction;
bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr);
var_ptr_instruction->value.data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack;
@@ -13356,8 +13440,7 @@ static ZigType *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instr
IrInstruction *casted_new_stack = nullptr;
if (call_instruction->new_stack != nullptr) {
ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
- false, false, PtrLenUnknown,
- get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 0, 0);
+ false, false, PtrLenUnknown, 0, 0, 0);
ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr);
IrInstruction *new_stack = call_instruction->new_stack->other;
if (type_is_invalid(new_stack->value.type))
@@ -13536,7 +13619,7 @@ static ZigType *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instr
inst_fn_type_id.return_type = specified_return_type;
}
- if ((err = type_ensure_zero_bits_known(ira->codegen, specified_return_type)))
+ if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
if (type_requires_comptime(specified_return_type)) {
@@ -14212,7 +14295,7 @@ static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) {
ptr_type->data.pointer.child_type,
ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
ptr_len,
- ptr_type->data.pointer.alignment,
+ ptr_type->data.pointer.explicit_alignment,
ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count);
}
@@ -14264,7 +14347,7 @@ static ZigType *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionEle
return_type = get_pointer_to_type_extra(ira->codegen, child_type,
ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
elem_ptr_instruction->ptr_len,
- ptr_type->data.pointer.alignment, 0, 0);
+ ptr_type->data.pointer.explicit_alignment, 0, 0);
} else {
uint64_t elem_val_scalar;
if (!ir_resolve_usize(ira, elem_index, &elem_val_scalar))
@@ -14336,7 +14419,7 @@ static ZigType *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionEle
uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type);
uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type);
- uint64_t ptr_align = return_type->data.pointer.alignment;
+ uint64_t ptr_align = get_ptr_align(ira->codegen, return_type);
if (instr_is_comptime(casted_elem_index)) {
uint64_t index = bigint_as_unsigned(&casted_elem_index->value.data.x_bigint);
if (array_type->id == ZigTypeIdArray) {
@@ -14653,9 +14736,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
}
ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
- is_const, is_volatile,
- PtrLenSingle,
- get_abi_alignment(ira->codegen, field_type), 0, 0);
+ is_const, is_volatile, PtrLenSingle, 0, 0, 0);
IrInstruction *result = ir_get_const(ira, source_instr);
ConstExprValue *const_val = &result->value;
@@ -14669,7 +14750,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field);
result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
- PtrLenSingle, get_abi_alignment(ira->codegen, field->type_entry), 0, 0);
+ PtrLenSingle, 0, 0, 0);
return result;
} else {
return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
@@ -15002,9 +15083,14 @@ static ZigType *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFi
} else if (buf_eql_str(field_name, "alignment")) {
bool ptr_is_const = true;
bool ptr_is_volatile = false;
+ if ((err = type_resolve(ira->codegen, child_type->data.pointer.child_type,
+ ResolveStatusAlignmentKnown)))
+ {
+ return ira->codegen->builtin_types.entry_invalid;
+ }
return ir_analyze_const_ptr(ira, &field_ptr_instruction->base,
create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int,
- child_type->data.pointer.alignment, false),
+ get_ptr_align(ira->codegen, child_type), false),
ira->codegen->builtin_types.entry_num_lit_int,
ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);
} else {
@@ -15461,7 +15547,7 @@ static ZigType *ir_analyze_instruction_slice_type(IrAnalyze *ira,
IrInstructionSliceType *slice_type_instruction)
{
Error err;
- uint32_t align_bytes;
+ uint32_t align_bytes = 0;
if (slice_type_instruction->align_value != nullptr) {
if (!ir_resolve_align(ira, slice_type_instruction->align_value->other, &align_bytes))
return ira->codegen->builtin_types.entry_invalid;
@@ -15471,12 +15557,6 @@ static ZigType *ir_analyze_instruction_slice_type(IrAnalyze *ira,
if (type_is_invalid(child_type))
return ira->codegen->builtin_types.entry_invalid;
- if (slice_type_instruction->align_value == nullptr) {
- if ((err = type_ensure_zero_bits_known(ira->codegen, child_type)))
- return ira->codegen->builtin_types.entry_invalid;
- align_bytes = get_abi_alignment(ira->codegen, child_type);
- }
-
bool is_const = slice_type_instruction->is_const;
bool is_volatile = slice_type_instruction->is_volatile;
@@ -15511,7 +15591,7 @@ static ZigType *ir_analyze_instruction_slice_type(IrAnalyze *ira,
case ZigTypeIdBoundFn:
case ZigTypeIdPromise:
{
- if ((err = type_ensure_zero_bits_known(ira->codegen, child_type)))
+ if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type,
is_const, is_volatile, PtrLenUnknown, align_bytes, 0, 0);
@@ -15751,9 +15831,7 @@ static ZigType *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira,
}
ZigType *child_type = type_entry->data.maybe.child_type;
ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type,
- ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
- PtrLenSingle,
- get_abi_alignment(ira->codegen, child_type), 0, 0);
+ ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0);
if (instr_is_comptime(value)) {
ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
@@ -16123,7 +16201,7 @@ static ZigType *ir_analyze_instruction_switch_target(IrAnalyze *ira,
return tag_type;
}
case ZigTypeIdEnum: {
- if ((err = type_ensure_zero_bits_known(ira->codegen, target_type)))
+ if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
if (target_type->data.enumeration.src_field_count < 2) {
TypeEnumField *only_field = &target_type->data.enumeration.fields[0];
@@ -16352,7 +16430,7 @@ static ZigType *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruc
if (casted_field_value == ira->codegen->invalid_instruction)
return ira->codegen->builtin_types.entry_invalid;
- if ((err = type_ensure_zero_bits_known(ira->codegen, casted_field_value->value.type)))
+ if ((err = type_resolve(ira->codegen, casted_field_value->value.type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope);
@@ -16752,7 +16830,7 @@ static ZigType *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstructionErr
return ira->codegen->builtin_types.entry_invalid;
ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
- true, false, PtrLenUnknown, get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 0, 0);
+ true, false, PtrLenUnknown, 0, 0, 0);
ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type);
if (casted_value->value.special == ConstValSpecialStatic) {
ErrorTableEntry *err = casted_value->value.data.x_err_set;
@@ -16779,7 +16857,7 @@ static ZigType *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructi
assert(target->value.type->id == ZigTypeIdEnum);
if (instr_is_comptime(target)) {
- if ((err = type_ensure_zero_bits_known(ira->codegen, target->value.type)))
+ if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
TypeEnumField *field = find_enum_field_by_tag(target->value.type, &target->value.data.x_bigint);
ConstExprValue *array_val = create_const_str_lit(ira->codegen, field->name);
@@ -16794,8 +16872,7 @@ static ZigType *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructi
ZigType *u8_ptr_type = get_pointer_to_type_extra(
ira->codegen, ira->codegen->builtin_types.entry_u8,
true, false, PtrLenUnknown,
- get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8),
- 0, 0);
+ 0, 0, 0);
result->value.type = get_slice_type(ira->codegen, u8_ptr_type);
return result->value.type;
}
@@ -17158,8 +17235,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
ZigType *u8_ptr = get_pointer_to_type_extra(
ira->codegen, ira->codegen->builtin_types.entry_u8,
true, false, PtrLenUnknown,
- get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8),
- 0, 0);
+ 0, 0, 0);
fn_def_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));
if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0) {
fn_def_fields[6].data.x_optional = create_const_vals(1);
@@ -17279,7 +17355,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty
ensure_field_index(result->type, "alignment", 3);
fields[3].special = ConstValSpecialStatic;
fields[3].type = get_int_type(ira->codegen, false, 29);
- bigint_init_unsigned(&fields[3].data.x_bigint, attrs_type->data.pointer.alignment);
+ bigint_init_unsigned(&fields[3].data.x_bigint, get_ptr_align(ira->codegen, attrs_type));
// child: type
ensure_field_index(result->type, "child", 4);
fields[4].special = ConstValSpecialStatic;
@@ -18369,7 +18445,21 @@ static ZigType *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstructio
return dest_type;
}
+static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) {
+ Error err;
+
+ if (ty->id == ZigTypeIdPointer) {
+ if ((err = type_resolve(ira->codegen, ty->data.pointer.child_type, ResolveStatusAlignmentKnown)))
+ return err;
+ }
+
+ *result_align = get_ptr_align(ira->codegen, ty);
+ return ErrorNone;
+}
+
static ZigType *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstructionFromBytes *instruction) {
+ Error err;
+
ZigType *dest_child_type = ir_resolve_type(ira, instruction->dest_child_type->other);
if (type_is_invalid(dest_child_type))
return ira->codegen->builtin_types.entry_invalid;
@@ -18384,15 +18474,23 @@ static ZigType *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstructionF
if (target->value.type->id == ZigTypeIdPointer) {
src_ptr_const = target->value.type->data.pointer.is_const;
src_ptr_volatile = target->value.type->data.pointer.is_volatile;
- src_ptr_align = target->value.type->data.pointer.alignment;
+
+ if ((err = resolve_ptr_align(ira, target->value.type, &src_ptr_align)))
+ return ira->codegen->builtin_types.entry_invalid;
} else if (is_slice(target->value.type)) {
ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry;
src_ptr_const = src_ptr_type->data.pointer.is_const;
src_ptr_volatile = src_ptr_type->data.pointer.is_volatile;
- src_ptr_align = src_ptr_type->data.pointer.alignment;
+
+ if ((err = resolve_ptr_align(ira, src_ptr_type, &src_ptr_align)))
+ return ira->codegen->builtin_types.entry_invalid;
} else {
src_ptr_const = true;
src_ptr_volatile = false;
+
+ if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusAlignmentKnown)))
+ return ira->codegen->builtin_types.entry_invalid;
+
src_ptr_align = get_abi_alignment(ira->codegen, target->value.type);
}
@@ -18450,6 +18548,8 @@ static ZigType *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstructionF
}
static ZigType *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) {
+ Error err;
+
IrInstruction *target = instruction->target->other;
if (type_is_invalid(target->value.type))
return ira->codegen->builtin_types.entry_invalid;
@@ -18462,9 +18562,13 @@ static ZigType *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToB
ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry;
+ uint32_t alignment;
+ if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment)))
+ return ira->codegen->builtin_types.entry_invalid;
+
ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
src_ptr_type->data.pointer.is_const, src_ptr_type->data.pointer.is_volatile, PtrLenUnknown,
- src_ptr_type->data.pointer.alignment, 0, 0);
+ alignment, 0, 0);
ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type);
IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_slice_type, CastOpResizeSlice, true);
@@ -18622,6 +18726,8 @@ static ZigType *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoo
}
static ZigType *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemset *instruction) {
+ Error err;
+
IrInstruction *dest_ptr = instruction->dest_ptr->other;
if (type_is_invalid(dest_ptr->value.type))
return ira->codegen->builtin_types.entry_invalid;
@@ -18640,8 +18746,13 @@ static ZigType *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemse
ZigType *usize = ira->codegen->builtin_types.entry_usize;
ZigType *u8 = ira->codegen->builtin_types.entry_u8;
- uint32_t dest_align = (dest_uncasted_type->id == ZigTypeIdPointer) ?
- dest_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8);
+ uint32_t dest_align;
+ if (dest_uncasted_type->id == ZigTypeIdPointer) {
+ if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align)))
+ return ira->codegen->builtin_types.entry_invalid;
+ } else {
+ dest_align = get_abi_alignment(ira->codegen, u8);
+ }
ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile,
PtrLenUnknown, dest_align, 0, 0);
@@ -18714,6 +18825,8 @@ static ZigType *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemse
}
static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcpy *instruction) {
+ Error err;
+
IrInstruction *dest_ptr = instruction->dest_ptr->other;
if (type_is_invalid(dest_ptr->value.type))
return ira->codegen->builtin_types.entry_invalid;
@@ -18733,10 +18846,22 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp
dest_uncasted_type->data.pointer.is_volatile;
bool src_is_volatile = (src_uncasted_type->id == ZigTypeIdPointer) &&
src_uncasted_type->data.pointer.is_volatile;
- uint32_t dest_align = (dest_uncasted_type->id == ZigTypeIdPointer) ?
- dest_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8);
- uint32_t src_align = (src_uncasted_type->id == ZigTypeIdPointer) ?
- src_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8);
+
+ uint32_t dest_align;
+ if (dest_uncasted_type->id == ZigTypeIdPointer) {
+ if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align)))
+ return ira->codegen->builtin_types.entry_invalid;
+ } else {
+ dest_align = get_abi_alignment(ira->codegen, u8);
+ }
+
+ uint32_t src_align;
+ if (src_uncasted_type->id == ZigTypeIdPointer) {
+ if ((err = resolve_ptr_align(ira, src_uncasted_type, &src_align)))
+ return ira->codegen->builtin_types.entry_invalid;
+ } else {
+ src_align = get_abi_alignment(ira->codegen, u8);
+ }
ZigType *usize = ira->codegen->builtin_types.entry_usize;
ZigType *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile,
@@ -18881,17 +19006,13 @@ static ZigType *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice
ZigType *return_type;
if (array_type->id == ZigTypeIdArray) {
- uint32_t byte_alignment = ptr_type->data.pointer.alignment;
- if (array_type->data.array.len == 0 && byte_alignment == 0) {
- byte_alignment = get_abi_alignment(ira->codegen, array_type->data.array.child_type);
- }
bool is_comptime_const = ptr_ptr->value.special == ConstValSpecialStatic &&
ptr_ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst;
ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type,
ptr_type->data.pointer.is_const || is_comptime_const,
ptr_type->data.pointer.is_volatile,
PtrLenUnknown,
- byte_alignment, 0, 0);
+ ptr_type->data.pointer.explicit_alignment, 0, 0);
return_type = get_slice_type(ira->codegen, slice_ptr_type);
} else if (array_type->id == ZigTypeIdPointer) {
if (array_type->data.pointer.ptr_len == PtrLenSingle) {
@@ -18901,7 +19022,7 @@ static ZigType *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice
main_type->data.pointer.child_type,
array_type->data.pointer.is_const, array_type->data.pointer.is_volatile,
PtrLenUnknown,
- array_type->data.pointer.alignment, 0, 0);
+ array_type->data.pointer.explicit_alignment, 0, 0);
return_type = get_slice_type(ira->codegen, slice_ptr_type);
} else {
ir_add_error(ira, &instruction->base, buf_sprintf("slice of single-item pointer"));
@@ -18911,7 +19032,7 @@ static ZigType *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice
ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.pointer.child_type,
array_type->data.pointer.is_const, array_type->data.pointer.is_volatile,
PtrLenUnknown,
- array_type->data.pointer.alignment, 0, 0);
+ array_type->data.pointer.explicit_alignment, 0, 0);
return_type = get_slice_type(ira->codegen, slice_ptr_type);
if (!end) {
ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value"));
@@ -19292,7 +19413,7 @@ static ZigType *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAli
return ira->codegen->builtin_types.entry_invalid;
ZigType *type_entry = ir_resolve_type(ira, type_value);
- if ((err = type_ensure_zero_bits_known(ira->codegen, type_entry)))
+ if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusAlignmentKnown)))
return ira->codegen->builtin_types.entry_invalid;
switch (type_entry->id) {
@@ -19336,6 +19457,8 @@ static ZigType *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAli
}
static ZigType *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) {
+ Error err;
+
IrInstruction *type_value = instruction->type_value->other;
if (type_is_invalid(type_value->value.type))
return ira->codegen->builtin_types.entry_invalid;
@@ -19379,10 +19502,13 @@ static ZigType *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstruction
ZigType *expected_ptr_type;
if (result_ptr->value.type->id == ZigTypeIdPointer) {
+ uint32_t alignment;
+ if ((err = resolve_ptr_align(ira, result_ptr->value.type, &alignment)))
+ return ira->codegen->builtin_types.entry_invalid;
expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type,
false, result_ptr->value.type->data.pointer.is_volatile,
PtrLenSingle,
- result_ptr->value.type->data.pointer.alignment, 0, 0);
+ alignment, 0, 0);
} else {
expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false);
}
@@ -19544,8 +19670,7 @@ static ZigType *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
}
ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type,
ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
- PtrLenSingle,
- get_abi_alignment(ira->codegen, payload_type), 0, 0);
+ PtrLenSingle, 0, 0, 0);
if (instr_is_comptime(value)) {
ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);
if (!ptr_val)
@@ -19624,7 +19749,7 @@ static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnP
ZigType *param_type = ir_resolve_type(ira, param_type_value);
if (type_is_invalid(param_type))
return ira->codegen->builtin_types.entry_invalid;
- if ((err = type_ensure_zero_bits_known(ira->codegen, param_type)))
+ if ((err = type_resolve(ira->codegen, param_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
if (type_requires_comptime(param_type)) {
if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
@@ -19899,7 +20024,7 @@ static ZigType *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructionPanic
}
ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
- true, false, PtrLenUnknown, get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 0, 0);
+ true, false, PtrLenUnknown, 0, 0, 0);
ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type);
IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type);
if (type_is_invalid(casted_msg->value.type))
@@ -19912,6 +20037,8 @@ static ZigType *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructionPanic
}
static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint32_t align_bytes, bool safety_check_on) {
+ Error err;
+
ZigType *target_type = target->value.type;
assert(!type_is_invalid(target_type));
@@ -19920,7 +20047,8 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3
if (target_type->id == ZigTypeIdPointer) {
result_type = adjust_ptr_align(ira->codegen, target_type, align_bytes);
- old_align_bytes = target_type->data.pointer.alignment;
+ if ((err = resolve_ptr_align(ira, target_type, &old_align_bytes)))
+ return ira->codegen->invalid_instruction;
} else if (target_type->id == ZigTypeIdFn) {
FnTypeId fn_type_id = target_type->data.fn.fn_type_id;
old_align_bytes = fn_type_id.alignment;
@@ -19930,7 +20058,8 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3
target_type->data.maybe.child_type->id == ZigTypeIdPointer)
{
ZigType *ptr_type = target_type->data.maybe.child_type;
- old_align_bytes = ptr_type->data.pointer.alignment;
+ if ((err = resolve_ptr_align(ira, ptr_type, &old_align_bytes)))
+ return ira->codegen->invalid_instruction;
ZigType *better_ptr_type = adjust_ptr_align(ira->codegen, ptr_type, align_bytes);
result_type = get_optional_type(ira->codegen, better_ptr_type);
@@ -19944,7 +20073,8 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3
result_type = get_optional_type(ira->codegen, fn_type);
} else if (is_slice(target_type)) {
ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry;
- old_align_bytes = slice_ptr_type->data.pointer.alignment;
+ if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes)))
+ return ira->codegen->invalid_instruction;
ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes);
result_type = get_slice_type(ira->codegen, result_ptr_type);
} else {
@@ -20023,8 +20153,13 @@ static ZigType *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtr
return dest_type;
}
- uint32_t src_align_bytes = get_ptr_align(ira->codegen, src_type);
- uint32_t dest_align_bytes = get_ptr_align(ira->codegen, dest_type);
+ uint32_t src_align_bytes;
+ if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes)))
+ return ira->codegen->builtin_types.entry_invalid;
+
+ uint32_t dest_align_bytes;
+ if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes)))
+ return ira->codegen->builtin_types.entry_invalid;
if (dest_align_bytes > src_align_bytes) {
ErrorMsg *msg = ir_add_error(ira, &instruction->base, buf_sprintf("cast increases pointer alignment"));
@@ -20041,7 +20176,7 @@ static ZigType *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtr
// Keep the bigger alignment, it can only help-
// unless the target is zero bits.
- if ((err = type_ensure_zero_bits_known(ira->codegen, dest_type)))
+ if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
IrInstruction *result;
@@ -20289,7 +20424,7 @@ static ZigType *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionI
return ira->codegen->builtin_types.entry_invalid;
}
- if ((err = type_ensure_zero_bits_known(ira->codegen, dest_type)))
+ if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
if (!type_has_bits(dest_type)) {
ir_add_error(ira, dest_type_value,
@@ -20440,12 +20575,15 @@ static ZigType *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtr
if (instruction->align_value != nullptr) {
if (!ir_resolve_align(ira, instruction->align_value->other, &align_bytes))
return ira->codegen->builtin_types.entry_invalid;
+ if ((err = type_resolve(ira->codegen, child_type, ResolveStatusAlignmentKnown)))
+ return ira->codegen->builtin_types.entry_invalid;
} else {
- if ((err = type_ensure_zero_bits_known(ira->codegen, child_type)))
+ if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
- align_bytes = get_abi_alignment(ira->codegen, child_type);
+ align_bytes = 0;
}
+
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type,
instruction->is_const, instruction->is_volatile,
@@ -21089,7 +21227,7 @@ static ZigType *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstruction
return ira->codegen->builtin_types.entry_invalid;
}
- if ((err = type_ensure_zero_bits_known(ira->codegen, target->value.type)))
+ if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
ZigType *tag_type = target->value.type->data.enumeration.tag_int_type;
@@ -21112,7 +21250,7 @@ static ZigType *ir_analyze_instruction_int_to_enum(IrAnalyze *ira, IrInstruction
return ira->codegen->builtin_types.entry_invalid;
}
- if ((err = type_ensure_zero_bits_known(ira->codegen, dest_type)))
+ if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
return ira->codegen->builtin_types.entry_invalid;
ZigType *tag_type = dest_type->data.enumeration.tag_int_type;