aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-03-07 12:18:41 -0500
committerAndrew Kelley <andrew@ziglang.org>2020-03-07 12:18:41 -0500
commit96c07674fc2293fa040212ab797c05436dc515b1 (patch)
tree67b0bc649f4b4c384259a031269254a90078c0bd /src/ir.cpp
parentbc75c0de6c8227d1c01b59c0d63f4d012e05496f (diff)
parentabe7305e169be2047d65f96e6525d3828684f058 (diff)
downloadzig-96c07674fc2293fa040212ab797c05436dc515b1.tar.gz
zig-96c07674fc2293fa040212ab797c05436dc515b1.zip
Merge remote-tracking branch 'origin/master' into llvm10
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp242
1 files changed, 156 insertions, 86 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index a2cc68b3ca..4068247b72 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -860,7 +860,7 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte
if (expected == actual)
return true;
- if (get_codegen_ptr_type(expected) != nullptr && get_codegen_ptr_type(actual) != nullptr)
+ if (get_src_ptr_type(expected) != nullptr && get_src_ptr_type(actual) != nullptr)
return true;
if (is_opt_err_set(expected) && is_opt_err_set(actual))
@@ -2766,9 +2766,24 @@ static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instructi
return &instruction->base;
}
-static IrInstSrc *ir_build_typeof(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) {
+static IrInstSrc *ir_build_typeof_n(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
+ IrInstSrc **values, size_t value_count)
+{
+ assert(value_count >= 2);
+
IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node);
- instruction->value = value;
+ instruction->value.list = values;
+ instruction->value_count = value_count;
+
+ for (size_t i = 0; i < value_count; i++)
+ ir_ref_instruction(values[i], irb->current_basic_block);
+
+ return &instruction->base;
+}
+
+static IrInstSrc *ir_build_typeof_1(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) {
+ IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node);
+ instruction->value.scalar = value;
ir_ref_instruction(value, irb->current_basic_block);
@@ -6043,7 +6058,7 @@ static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstN
if (fn_ref == irb->codegen->invalid_inst_src)
return fn_ref;
- IrInstSrc *fn_type = ir_build_typeof(irb, scope, source_node, fn_ref);
+ IrInstSrc *fn_type = ir_build_typeof_1(irb, scope, source_node, fn_ref);
IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len);
for (size_t i = 0; i < args_len; i += 1) {
@@ -6104,12 +6119,33 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
{
Scope *sub_scope = create_typeof_scope(irb->codegen, node, scope);
- AstNode *arg_node = node->data.fn_call_expr.params.at(0);
- IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope);
- if (arg == irb->codegen->invalid_inst_src)
- return arg;
+ size_t arg_count = node->data.fn_call_expr.params.length;
+
+ IrInstSrc *type_of;
- IrInstSrc *type_of = ir_build_typeof(irb, scope, node, arg);
+ if (arg_count == 0) {
+ add_node_error(irb->codegen, node,
+ buf_sprintf("expected at least 1 argument, found 0"));
+ return irb->codegen->invalid_inst_src;
+ } else if (arg_count == 1) {
+ AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
+ IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, sub_scope);
+ if (arg0_value == irb->codegen->invalid_inst_src)
+ return arg0_value;
+
+ type_of = ir_build_typeof_1(irb, scope, node, arg0_value);
+ } else {
+ IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count);
+ for (size_t i = 0; i < arg_count; i += 1) {
+ AstNode *arg_node = node->data.fn_call_expr.params.at(i);
+ IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope);
+ if (arg == irb->codegen->invalid_inst_src)
+ return irb->codegen->invalid_inst_src;
+ args[i] = arg;
+ }
+
+ type_of = ir_build_typeof_n(irb, scope, node, args, arg_count);
+ }
return ir_lval_wrap(irb, scope, type_of, lval, result_loc);
}
case BuiltinFnIdSetCold:
@@ -11366,7 +11402,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))
@@ -12499,7 +12535,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))
@@ -12885,7 +12921,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,
@@ -13049,7 +13085,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)));
@@ -13165,7 +13205,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;
@@ -13213,7 +13253,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) ||
@@ -13325,7 +13365,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) ||
@@ -13352,7 +13392,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;
@@ -13401,7 +13442,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;
@@ -13646,9 +13687,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;
@@ -15005,7 +15046,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) {
@@ -15265,7 +15306,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);
@@ -15354,7 +15395,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) {
@@ -15373,7 +15414,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;
@@ -16211,7 +16252,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) {
@@ -16928,8 +16969,6 @@ static IrInstGen *ir_analyze_tuple_cat(IrAnalyze *ira, IrInst* source_instr,
new_type->data.structure.special = StructSpecialInferredTuple;
new_type->data.structure.resolve_status = ResolveStatusBeingInferred;
- bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope);
-
IrInstGen *new_struct_ptr = ir_resolve_result(ira, source_instr, no_result_loc(),
new_type, nullptr, false, true);
uint32_t new_field_count = op1_field_count + op2_field_count;
@@ -16957,7 +16996,6 @@ static IrInstGen *ir_analyze_tuple_cat(IrAnalyze *ira, IrInst* source_instr,
return ira->codegen->invalid_inst_gen;
ZigList<IrInstGen *> const_ptrs = {};
- IrInstGen *first_non_const_instruction = nullptr;
for (uint32_t i = 0; i < new_field_count; i += 1) {
TypeStructField *dst_field = new_type->data.structure.fields[i];
IrInstGen *src_struct_op;
@@ -16979,8 +17017,6 @@ static IrInstGen *ir_analyze_tuple_cat(IrAnalyze *ira, IrInst* source_instr,
return ira->codegen->invalid_inst_gen;
if (instr_is_comptime(field_value)) {
const_ptrs.append(dest_ptr);
- } else {
- first_non_const_instruction = field_value;
}
IrInstGen *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, dest_ptr, field_value,
true);
@@ -16997,20 +17033,13 @@ static IrInstGen *ir_analyze_tuple_cat(IrAnalyze *ira, IrInst* source_instr,
continue;
}
IrInstGen *deref = ir_get_deref(ira, &elem_result_loc->base, elem_result_loc, nullptr);
- elem_result_loc->value->special = ConstValSpecialRuntime;
- ir_analyze_store_ptr(ira, &elem_result_loc->base, elem_result_loc, deref, false);
+ if (!type_requires_comptime(ira->codegen, elem_result_loc->value->type->data.pointer.child_type)) {
+ elem_result_loc->value->special = ConstValSpecialRuntime;
+ }
+ ir_analyze_store_ptr(ira, &elem_result_loc->base, elem_result_loc, deref, true);
}
}
IrInstGen *result = ir_get_deref(ira, source_instr, new_struct_ptr, nullptr);
- if (instr_is_comptime(result))
- return result;
-
- if (is_comptime) {
- ir_add_error(ira, &first_non_const_instruction->base,
- buf_sprintf("unable to evaluate constant expression"));
- return ira->codegen->invalid_inst_gen;
- }
-
return result;
}
@@ -17861,7 +17890,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;
@@ -18250,7 +18279,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,
@@ -18295,7 +18324,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;
@@ -18307,7 +18339,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;
@@ -18367,7 +18402,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);
@@ -19085,7 +19120,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);
@@ -19214,7 +19249,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);
@@ -19333,7 +19368,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) {
@@ -19350,7 +19385,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;
}
@@ -19402,7 +19437,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 {
@@ -19471,7 +19506,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) {
@@ -19488,7 +19523,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;
}
@@ -21630,10 +21665,31 @@ static IrInstGen *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstSrcLoadP
}
static IrInstGen *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstSrcTypeOf *typeof_instruction) {
- IrInstGen *expr_value = typeof_instruction->value->child;
- ZigType *type_entry = expr_value->value->type;
+ ZigType *type_entry;
+
+ const size_t value_count = typeof_instruction->value_count;
+
+ // Fast path for the common case of TypeOf with a single argument
+ if (value_count < 2) {
+ type_entry = typeof_instruction->value.scalar->child->value->type;
+ } else {
+ IrInstGen **args = heap::c_allocator.allocate<IrInstGen*>(value_count);
+ for (size_t i = 0; i < value_count; i += 1) {
+ IrInstGen *value = typeof_instruction->value.list[i]->child;
+ if (type_is_invalid(value->value->type))
+ return ira->codegen->invalid_inst_gen;
+ args[i] = value;
+ }
+
+ type_entry = ir_resolve_peer_types(ira, typeof_instruction->base.base.source_node,
+ nullptr, args, value_count);
+
+ heap::c_allocator.deallocate(args, value_count);
+ }
+
if (type_is_invalid(type_entry))
return ira->codegen->invalid_inst_gen;
+
return ir_const_type(ira, &typeof_instruction->base.base, type_entry);
}
@@ -23021,8 +23077,11 @@ static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
}
}
+ const_ptrs.deinit();
+
IrInstGen *result = ir_get_deref(ira, &instruction->base.base, result_loc, nullptr);
- if (instr_is_comptime(result))
+ // If the result is a tuple, we are allowed to return a struct that uses ConstValSpecialRuntime fields at comptime.
+ if (instr_is_comptime(result) || is_tuple(container_type))
return result;
if (is_comptime) {
@@ -23313,7 +23372,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)));
@@ -24231,7 +24290,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;
@@ -24247,7 +24306,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
// default_value: var
inner_fields[3]->special = ConstValSpecialStatic;
- inner_fields[3]->type = get_optional_type(ira->codegen, struct_field->type_entry);
+ inner_fields[3]->type = get_optional_type2(ira->codegen, struct_field->type_entry);
+ if (inner_fields[3]->type == nullptr) return ErrorSemanticAnalyzeFail;
memoize_field_init_val(ira->codegen, type_entry, struct_field);
set_optional_payload(inner_fields[3], struct_field->init_val);
@@ -24956,9 +25016,7 @@ static IrInstGen *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstSrcEmb
}
}
- ZigType *result_type = get_array_type(ira->codegen,
- ira->codegen->builtin_types.entry_u8, buf_len(file_contents), nullptr);
- IrInstGen *result = ir_const(ira, &instruction->base.base, result_type);
+ IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
init_const_str_lit(ira->codegen, result->value, file_contents);
return result;
}
@@ -25044,7 +25102,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) {
@@ -25363,8 +25421,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) {
@@ -27331,7 +27392,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)));
@@ -27390,7 +27451,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);
}
@@ -27411,7 +27472,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;
@@ -27769,9 +27830,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) {
@@ -27830,7 +27889,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))
@@ -27948,7 +28007,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);
@@ -28199,10 +28258,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;
@@ -28633,15 +28699,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);
@@ -29042,7 +29112,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 &&
@@ -29092,7 +29162,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) {
@@ -29112,7 +29182,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;
@@ -30155,7 +30225,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;