authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-22 12:07:56-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-22 12:08:04-04:00
log8460d5617cc12d614abf39f55ab85c783c4b35a8
treed413b93daea85d0c87582823c78da46f2910251e
parentefdbede7abf91d5fe2836d95987a83e95e9fcf8e
signaturelock-open Commit is signed but in an unrecognized format.

introduce lazy values

see #2174

7 files changed, 320 insertions(+), 136 deletions(-)

BRANCH_TODO created+3
...@@ -0,0 +1,3 @@
1* slice type and ptr type instructions need to implicit cast alignment
2* fix regressions of error notes with "called from here"
3* fix tests
src/all_types.hpp+51-10
...@@ -47,6 +47,12 @@ struct ResultLocPeer;...@@ -47,6 +47,12 @@ struct ResultLocPeer;
47struct ResultLocPeerParent;47struct ResultLocPeerParent;
48struct ResultLocBitCast;48struct ResultLocBitCast;
4949
50enum PtrLen {
51 PtrLenUnknown,
52 PtrLenSingle,
53 PtrLenC,
54};
55
50enum X64CABIClass {56enum X64CABIClass {
51 X64CABIClass_Unknown,57 X64CABIClass_Unknown,
52 X64CABIClass_MEMORY,58 X64CABIClass_MEMORY,
...@@ -255,6 +261,7 @@ enum ConstValSpecial {...@@ -255,6 +261,7 @@ enum ConstValSpecial {
255 ConstValSpecialRuntime,261 ConstValSpecialRuntime,
256 ConstValSpecialStatic,262 ConstValSpecialStatic,
257 ConstValSpecialUndef,263 ConstValSpecialUndef,
264 ConstValSpecialLazy,
258};265};
259266
260enum RuntimeHintErrorUnion {267enum RuntimeHintErrorUnion {
...@@ -291,6 +298,44 @@ struct ConstGlobalRefs {...@@ -291,6 +298,44 @@ struct ConstGlobalRefs {
291 uint32_t align;298 uint32_t align;
292};299};
293300
301enum LazyValueId {
302 LazyValueIdInvalid,
303 LazyValueIdAlignOf,
304 LazyValueIdPtrType,
305 LazyValueIdSliceType,
306};
307
308struct LazyValue {
309 LazyValueId id;
310 IrExecutable *exec;
311};
312
313struct LazyValueAlignOf {
314 LazyValue base;
315 ZigType *target_type;
316};
317
318struct LazyValueSliceType {
319 LazyValue base;
320 ZigType *elem_type;
321 ConstExprValue *align_val; // can be null
322 bool is_const;
323 bool is_volatile;
324 bool is_allowzero;
325};
326
327struct LazyValuePtrType {
328 LazyValue base;
329 ZigType *elem_type;
330 ConstExprValue *align_val; // can be null
331 PtrLen ptr_len;
332 uint32_t bit_offset_in_host;
333 uint32_t host_int_bytes;
334 bool is_const;
335 bool is_volatile;
336 bool is_allowzero;
337};
338
294struct ConstExprValue {339struct ConstExprValue {
295 ZigType *type;340 ZigType *type;
296 ConstValSpecial special;341 ConstValSpecial special;
...@@ -318,6 +363,7 @@ struct ConstExprValue {...@@ -318,6 +363,7 @@ struct ConstExprValue {
318 ConstPtrValue x_ptr;363 ConstPtrValue x_ptr;
319 ConstArgTuple x_arg_tuple;364 ConstArgTuple x_arg_tuple;
320 Buf *x_enum_literal;365 Buf *x_enum_literal;
366 LazyValue *x_lazy;
321367
322 // populated if special == ConstValSpecialRuntime368 // populated if special == ConstValSpecialRuntime
323 RuntimeHintErrorUnion rh_error_union;369 RuntimeHintErrorUnion rh_error_union;
...@@ -1039,12 +1085,6 @@ struct FnTypeId {...@@ -1039,12 +1085,6 @@ struct FnTypeId {
1039uint32_t fn_type_id_hash(FnTypeId*);1085uint32_t fn_type_id_hash(FnTypeId*);
1040bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);1086bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);
10411087
1042enum PtrLen {
1043 PtrLenUnknown,
1044 PtrLenSingle,
1045 PtrLenC,
1046};
1047
1048struct ZigTypePointer {1088struct ZigTypePointer {
1049 ZigType *child_type;1089 ZigType *child_type;
1050 ZigType *slice_parent;1090 ZigType *slice_parent;
...@@ -1073,7 +1113,8 @@ struct ZigTypeArray {...@@ -1073,7 +1113,8 @@ struct ZigTypeArray {
10731113
1074struct TypeStructField {1114struct TypeStructField {
1075 Buf *name;1115 Buf *name;
1076 ZigType *type_entry;1116 ZigType *type_entry; // available after ResolveStatusSizeKnown
1117 ConstExprValue *type_val; // available after ResolveStatusZeroBitsKnown
1077 size_t src_index;1118 size_t src_index;
1078 size_t gen_index;1119 size_t gen_index;
1079 size_t offset; // byte offset from beginning of struct1120 size_t offset; // byte offset from beginning of struct
...@@ -1931,7 +1972,7 @@ struct CodeGen {...@@ -1931,7 +1972,7 @@ struct CodeGen {
1931 Buf *zig_lib_dir;1972 Buf *zig_lib_dir;
1932 Buf *zig_std_dir;1973 Buf *zig_std_dir;
1933 Buf *dynamic_linker_path;1974 Buf *dynamic_linker_path;
1934 Buf *version_script_path; 1975 Buf *version_script_path;
19351976
1936 const char **llvm_argv;1977 const char **llvm_argv;
1937 size_t llvm_argv_len;1978 size_t llvm_argv_len;
...@@ -3648,13 +3689,13 @@ enum ResultLocId {...@@ -3648,13 +3689,13 @@ enum ResultLocId {
3648 ResultLocIdBitCast,3689 ResultLocIdBitCast,
3649};3690};
36503691
3651// Additions to this struct may need to be handled in 3692// Additions to this struct may need to be handled in
3652// ir_reset_result3693// ir_reset_result
3653struct ResultLoc {3694struct ResultLoc {
3654 ResultLocId id;3695 ResultLocId id;
3655 bool written;3696 bool written;
3656 bool allow_write_through_const;3697 bool allow_write_through_const;
3657 IrInstruction *resolved_loc; // result ptr 3698 IrInstruction *resolved_loc; // result ptr
3658 IrInstruction *source_instruction;3699 IrInstruction *source_instruction;
3659 IrInstruction *gen_instruction; // value to store to the result loc3700 IrInstruction *gen_instruction; // value to store to the result loc
3660 ZigType *implicit_elem_type;3701 ZigType *implicit_elem_type;
src/analyze.cpp+33-23
...@@ -445,8 +445,6 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons...@@ -445,8 +445,6 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
445 }445 }
446 }446 }
447447
448 assert(type_is_resolved(child_type, ResolveStatusZeroBitsKnown));
449
450 ZigType *entry = new_type_table_entry(ZigTypeIdPointer);448 ZigType *entry = new_type_table_entry(ZigTypeIdPointer);
451449
452 const char *star_str = ptr_len_to_star_str(ptr_len);450 const char *star_str = ptr_len_to_star_str(ptr_len);
...@@ -476,8 +474,6 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons...@@ -476,8 +474,6 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
476 buf_ptr(&child_type->name));474 buf_ptr(&child_type->name));
477 }475 }
478476
479 assert(child_type->id != ZigTypeIdInvalid);
480
481 if (type_has_bits(child_type)) {477 if (type_has_bits(child_type)) {
482 entry->abi_size = g->builtin_types.entry_usize->abi_size;478 entry->abi_size = g->builtin_types.entry_usize->abi_size;
483 entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;479 entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
...@@ -689,7 +685,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {...@@ -689,7 +685,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
689 entry->data.structure.fields_by_name.put(ptr_field_name, &entry->data.structure.fields[slice_ptr_index]);685 entry->data.structure.fields_by_name.put(ptr_field_name, &entry->data.structure.fields[slice_ptr_index]);
690 entry->data.structure.fields_by_name.put(len_field_name, &entry->data.structure.fields[slice_len_index]);686 entry->data.structure.fields_by_name.put(len_field_name, &entry->data.structure.fields[slice_len_index]);
691687
692 switch (type_requires_comptime(g, ptr_type)) {688 switch (type_requires_comptime(g, ptr_type, entry)) {
693 case ReqCompTimeInvalid:689 case ReqCompTimeInvalid:
694 zig_unreachable();690 zig_unreachable();
695 case ReqCompTimeNo:691 case ReqCompTimeNo:
...@@ -945,12 +941,18 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind...@@ -945,12 +941,18 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind
945 return entry;941 return entry;
946}942}
947943
948ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name) {944ConstExprValue *analyze_const_value_allow_lazy(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry,
945 Buf *type_name, bool allow_lazy)
946{
949 size_t backward_branch_count = 0;947 size_t backward_branch_count = 0;
950 size_t backward_branch_quota = default_backward_branch_quota;948 size_t backward_branch_quota = default_backward_branch_quota;
951 return ir_eval_const_value(g, scope, node, type_entry,949 return ir_eval_const_value(g, scope, node, type_entry,
952 &backward_branch_count, &backward_branch_quota,950 &backward_branch_count, &backward_branch_quota,
953 nullptr, nullptr, node, type_name, nullptr, nullptr);951 nullptr, nullptr, node, type_name, nullptr, nullptr, allow_lazy);
952}
953
954ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name) {
955 return analyze_const_value_allow_lazy(g, scope, node, type_entry, type_name, false);
954}956}
955957
956ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {958ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
...@@ -1355,7 +1357,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc...@@ -1355,7 +1357,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
1355 case ZigTypeIdVector:1357 case ZigTypeIdVector:
1356 case ZigTypeIdFnFrame:1358 case ZigTypeIdFnFrame:
1357 case ZigTypeIdAnyFrame:1359 case ZigTypeIdAnyFrame:
1358 switch (type_requires_comptime(g, type_entry)) {1360 switch (type_requires_comptime(g, type_entry, fn_entry->type_entry)) {
1359 case ReqCompTimeNo:1361 case ReqCompTimeNo:
1360 break;1362 break;
1361 case ReqCompTimeYes:1363 case ReqCompTimeYes:
...@@ -1451,7 +1453,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc...@@ -1451,7 +1453,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
1451 case ZigTypeIdVector:1453 case ZigTypeIdVector:
1452 case ZigTypeIdFnFrame:1454 case ZigTypeIdFnFrame:
1453 case ZigTypeIdAnyFrame:1455 case ZigTypeIdAnyFrame:
1454 switch (type_requires_comptime(g, fn_type_id.return_type)) {1456 switch (type_requires_comptime(g, fn_type_id.return_type, fn_entry->type_entry)) {
1455 case ReqCompTimeInvalid:1457 case ReqCompTimeInvalid:
1456 return g->builtin_types.entry_invalid;1458 return g->builtin_types.entry_invalid;
1457 case ReqCompTimeYes:1459 case ReqCompTimeYes:
...@@ -2164,7 +2166,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2164,7 +2166,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2164 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2166 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2165 return ErrorSemanticAnalyzeFail;2167 return ErrorSemanticAnalyzeFail;
2166 }2168 }
2167 switch (type_requires_comptime(g, field_type)) {2169 switch (type_requires_comptime(g, field_type, struct_type)) {
2168 case ReqCompTimeYes:2170 case ReqCompTimeYes:
2169 struct_type->data.structure.requires_comptime = true;2171 struct_type->data.structure.requires_comptime = true;
2170 break;2172 break;
...@@ -2422,7 +2424,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -2422,7 +2424,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
2422 return ErrorSemanticAnalyzeFail;2424 return ErrorSemanticAnalyzeFail;
2423 }2425 }
24242426
2425 switch (type_requires_comptime(g, field_type)) {2427 switch (type_requires_comptime(g, field_type, union_type)) {
2426 case ReqCompTimeInvalid:2428 case ReqCompTimeInvalid:
2427 union_type->data.unionation.resolve_status = ResolveStatusInvalid;2429 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2428 return ErrorSemanticAnalyzeFail;2430 return ErrorSemanticAnalyzeFail;
...@@ -4754,11 +4756,12 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {...@@ -4754,11 +4756,12 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
4754 zig_unreachable();4756 zig_unreachable();
4755}4757}
47564758
4757ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {4759ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty, ZigType *parent_type) {
4758 Error err;4760 Error err;
4759 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))4761 if (ty == parent_type) {
4760 return ReqCompTimeInvalid;4762 return ReqCompTimeNo;
4761 switch (type_entry->id) {4763 }
4764 switch (ty->id) {
4762 case ZigTypeIdInvalid:4765 case ZigTypeIdInvalid:
4763 case ZigTypeIdOpaque:4766 case ZigTypeIdOpaque:
4764 zig_unreachable();4767 zig_unreachable();
...@@ -4772,23 +4775,27 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {...@@ -4772,23 +4775,27 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
4772 case ZigTypeIdArgTuple:4775 case ZigTypeIdArgTuple:
4773 return ReqCompTimeYes;4776 return ReqCompTimeYes;
4774 case ZigTypeIdArray:4777 case ZigTypeIdArray:
4775 return type_requires_comptime(g, type_entry->data.array.child_type);4778 return type_requires_comptime(g, ty->data.array.child_type, parent_type);
4776 case ZigTypeIdStruct:4779 case ZigTypeIdStruct:
4777 return type_entry->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;4780 if ((err = type_resolve(g, ty, ResolveStatusZeroBitsKnown)))
4781 return ReqCompTimeInvalid;
4782 return ty->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
4778 case ZigTypeIdUnion:4783 case ZigTypeIdUnion:
4779 return type_entry->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;4784 if ((err = type_resolve(g, ty, ResolveStatusZeroBitsKnown)))
4785 return ReqCompTimeInvalid;
4786 return ty->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
4780 case ZigTypeIdOptional:4787 case ZigTypeIdOptional:
4781 return type_requires_comptime(g, type_entry->data.maybe.child_type);4788 return type_requires_comptime(g, ty->data.maybe.child_type, parent_type);
4782 case ZigTypeIdErrorUnion:4789 case ZigTypeIdErrorUnion:
4783 return type_requires_comptime(g, type_entry->data.error_union.payload_type);4790 return type_requires_comptime(g, ty->data.error_union.payload_type, parent_type);
4784 case ZigTypeIdPointer:4791 case ZigTypeIdPointer:
4785 if (type_entry->data.pointer.child_type->id == ZigTypeIdOpaque) {4792 if (ty->data.pointer.child_type->id == ZigTypeIdOpaque) {
4786 return ReqCompTimeNo;4793 return ReqCompTimeNo;
4787 } else {4794 } else {
4788 return type_requires_comptime(g, type_entry->data.pointer.child_type);4795 return type_requires_comptime(g, ty->data.pointer.child_type, parent_type);
4789 }4796 }
4790 case ZigTypeIdFn:4797 case ZigTypeIdFn:
4791 return type_entry->data.fn.is_generic ? ReqCompTimeYes : ReqCompTimeNo;4798 return ty->data.fn.is_generic ? ReqCompTimeYes : ReqCompTimeNo;
4792 case ZigTypeIdEnum:4799 case ZigTypeIdEnum:
4793 case ZigTypeIdErrorSet:4800 case ZigTypeIdErrorSet:
4794 case ZigTypeIdBool:4801 case ZigTypeIdBool:
...@@ -5726,6 +5733,9 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -5726,6 +5733,9 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
5726 case ConstValSpecialRuntime:5733 case ConstValSpecialRuntime:
5727 buf_appendf(buf, "(runtime value)");5734 buf_appendf(buf, "(runtime value)");
5728 return;5735 return;
5736 case ConstValSpecialLazy:
5737 buf_appendf(buf, "(lazy value)");
5738 return;
5729 case ConstValSpecialUndef:5739 case ConstValSpecialUndef:
5730 buf_appendf(buf, "undefined");5740 buf_appendf(buf, "undefined");
5731 return;5741 return;
src/analyze.hpp+3-1
...@@ -221,7 +221,7 @@ enum ReqCompTime {...@@ -221,7 +221,7 @@ enum ReqCompTime {
221 ReqCompTimeNo,221 ReqCompTimeNo,
222 ReqCompTimeYes,222 ReqCompTimeYes,
223};223};
224ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry);224ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry, ZigType *parent_type);
225225
226OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry);226OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry);
227227
...@@ -241,6 +241,8 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa...@@ -241,6 +241,8 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
241void src_assert(bool ok, AstNode *source_node);241void src_assert(bool ok, AstNode *source_node);
242bool is_container(ZigType *type_entry);242bool is_container(ZigType *type_entry);
243ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name);243ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name);
244ConstExprValue *analyze_const_value_allow_lazy(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry,
245 Buf *type_name, bool allow_lazy);
244246
245void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);247void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
246bool fn_is_async(ZigFn *fn);248bool fn_is_async(ZigFn *fn);
src/codegen.cpp+7-2
...@@ -3386,6 +3386,8 @@ static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) {...@@ -3386,6 +3386,8 @@ static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) {
33863386
3387static bool value_is_all_undef(ConstExprValue *const_val) {3387static bool value_is_all_undef(ConstExprValue *const_val) {
3388 switch (const_val->special) {3388 switch (const_val->special) {
3389 case ConstValSpecialLazy:
3390 zig_unreachable();
3389 case ConstValSpecialRuntime:3391 case ConstValSpecialRuntime:
3390 return false;3392 return false;
3391 case ConstValSpecialUndef:3393 case ConstValSpecialUndef:
...@@ -3686,7 +3688,7 @@ static void render_async_spills(CodeGen *g) {...@@ -3686,7 +3688,7 @@ static void render_async_spills(CodeGen *g) {
3686 }3688 }
3687 if (ir_get_var_is_comptime(var))3689 if (ir_get_var_is_comptime(var))
3688 continue;3690 continue;
3689 switch (type_requires_comptime(g, var->var_type)) {3691 switch (type_requires_comptime(g, var->var_type, nullptr)) {
3690 case ReqCompTimeInvalid:3692 case ReqCompTimeInvalid:
3691 zig_unreachable();3693 zig_unreachable();
3692 case ReqCompTimeYes:3694 case ReqCompTimeYes:
...@@ -6041,6 +6043,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un...@@ -6041,6 +6043,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un
60416043
6042static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ConstExprValue *const_val) {6044static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ConstExprValue *const_val) {
6043 switch (const_val->special) {6045 switch (const_val->special) {
6046 case ConstValSpecialLazy:
6044 case ConstValSpecialRuntime:6047 case ConstValSpecialRuntime:
6045 zig_unreachable();6048 zig_unreachable();
6046 case ConstValSpecialUndef:6049 case ConstValSpecialUndef:
...@@ -6300,6 +6303,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -6300,6 +6303,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
6300 assert(type_has_bits(type_entry));6303 assert(type_has_bits(type_entry));
63016304
6302 switch (const_val->special) {6305 switch (const_val->special) {
6306 case ConstValSpecialLazy:
6307 zig_unreachable();
6303 case ConstValSpecialRuntime:6308 case ConstValSpecialRuntime:
6304 zig_unreachable();6309 zig_unreachable();
6305 case ConstValSpecialUndef:6310 case ConstValSpecialUndef:
...@@ -7044,7 +7049,7 @@ static void do_code_gen(CodeGen *g) {...@@ -7044,7 +7049,7 @@ static void do_code_gen(CodeGen *g) {
7044 }7049 }
7045 if (ir_get_var_is_comptime(var))7050 if (ir_get_var_is_comptime(var))
7046 continue;7051 continue;
7047 switch (type_requires_comptime(g, var->var_type)) {7052 switch (type_requires_comptime(g, var->var_type, nullptr)) {
7048 case ReqCompTimeInvalid:7053 case ReqCompTimeInvalid:
7049 zig_unreachable();7054 zig_unreachable();
7050 case ReqCompTimeYes:7055 case ReqCompTimeYes:
src/ir.cpp+220-99
...@@ -155,6 +155,7 @@ struct ConstCastBadAllowsZero {...@@ -155,6 +155,7 @@ struct ConstCastBadAllowsZero {
155enum UndefAllowed {155enum UndefAllowed {
156 UndefOk,156 UndefOk,
157 UndefBad,157 UndefBad,
158 LazyOk,
158};159};
159160
160static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);161static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
...@@ -403,7 +404,7 @@ static void ir_ref_var(ZigVar *var) {...@@ -403,7 +404,7 @@ static void ir_ref_var(ZigVar *var) {
403ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {404ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {
404 ConstExprValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type,405 ConstExprValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type,
405 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr,406 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr,
406 node, nullptr, ira->new_irb.exec, nullptr);407 node, nullptr, ira->new_irb.exec, nullptr, false);
407408
408 if (type_is_invalid(result->type))409 if (type_is_invalid(result->type))
409 return ira->codegen->builtin_types.entry_invalid;410 return ira->codegen->builtin_types.entry_invalid;
...@@ -10710,32 +10711,57 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio...@@ -10710,32 +10711,57 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio
10710 return const_instr;10711 return const_instr;
10711}10712}
1071210713
10714static Error ir_resolve_const_val(CodeGen *codegen, IrExecutable *exec, AstNode *source_node,
10715 ConstExprValue *val, UndefAllowed undef_allowed)
10716{
10717 Error err;
10718 for (;;) {
10719 switch (val->special) {
10720 case ConstValSpecialStatic:
10721 return ErrorNone;
10722 case ConstValSpecialRuntime:
10723 if (!type_has_bits(val->type))
10724 return ErrorNone;
10725
10726 exec_add_error_node(codegen, exec, source_node,
10727 buf_sprintf("unable to evaluate constant expression"));
10728 return ErrorSemanticAnalyzeFail;
10729 case ConstValSpecialUndef:
10730 if (undef_allowed == UndefOk)
10731 return ErrorNone;
10732
10733 exec_add_error_node(codegen, exec, source_node,
10734 buf_sprintf("use of undefined value here causes undefined behavior"));
10735 return ErrorSemanticAnalyzeFail;
10736 case ConstValSpecialLazy:
10737 if (undef_allowed == LazyOk)
10738 return ErrorNone;
10739
10740 if ((err = ir_resolve_lazy(codegen, source_node, val)))
10741 return err;
10742
10743 continue;
10744 }
10745 }
10746}
10747
10713static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) {10748static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) {
10714 switch (value->value.special) {10749 Error err;
10715 case ConstValSpecialStatic:10750 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, value->source_node,
10716 return &value->value;10751 &value->value, undef_allowed)))
10717 case ConstValSpecialRuntime:10752 {
10718 if (!type_has_bits(value->value.type)) {10753 return nullptr;
10719 return &value->value;
10720 }
10721 ir_add_error(ira, value, buf_sprintf("unable to evaluate constant expression"));
10722 return nullptr;
10723 case ConstValSpecialUndef:
10724 if (undef_allowed == UndefOk) {
10725 return &value->value;
10726 } else {
10727 ir_add_error(ira, value, buf_sprintf("use of undefined value here causes undefined behavior"));
10728 return nullptr;
10729 }
10730 }10754 }
10731 zig_unreachable();10755 return &value->value;
10732}10756}
1073310757
10734ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,10758ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
10735 ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota,10759 ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota,
10736 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,10760 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
10737 IrExecutable *parent_exec, AstNode *expected_type_source_node)10761 IrExecutable *parent_exec, AstNode *expected_type_source_node, bool allow_lazy)
10738{10762{
10763 Error err;
10764
10739 if (expected_type != nullptr && type_is_invalid(expected_type))10765 if (expected_type != nullptr && type_is_invalid(expected_type))
10740 return &codegen->invalid_instruction->value;10766 return &codegen->invalid_instruction->value;
1074110767
...@@ -10784,7 +10810,14 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod...@@ -10784,7 +10810,14 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod
10784 fprintf(stderr, "}\n");10810 fprintf(stderr, "}\n");
10785 }10811 }
1078610812
10787 return ir_exec_const_result(codegen, analyzed_executable);10813 ConstExprValue *result = ir_exec_const_result(codegen, analyzed_executable);
10814
10815 if (!allow_lazy) {
10816 if ((err = ir_resolve_lazy(codegen, node, result)))
10817 return &codegen->invalid_instruction->value;
10818 }
10819
10820 return result;
10788}10821}
1078910822
10790static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_value) {10823static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_value) {
...@@ -10805,6 +10838,17 @@ static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_valu...@@ -10805,6 +10838,17 @@ static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_valu
10805 return const_val->data.x_err_set;10838 return const_val->data.x_err_set;
10806}10839}
1080710840
10841static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node,
10842 ConstExprValue *val)
10843{
10844 Error err;
10845 if ((err = ir_resolve_const_val(codegen, exec, source_node, val, UndefBad)))
10846 return codegen->builtin_types.entry_invalid;
10847
10848 assert(val->data.x_type != nullptr);
10849 return val->data.x_type;
10850}
10851
10808static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) {10852static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) {
10809 if (type_is_invalid(type_value->value.type))10853 if (type_is_invalid(type_value->value.type))
10810 return ira->codegen->builtin_types.entry_invalid;10854 return ira->codegen->builtin_types.entry_invalid;
...@@ -10815,12 +10859,7 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) {...@@ -10815,12 +10859,7 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) {
10815 return ira->codegen->builtin_types.entry_invalid;10859 return ira->codegen->builtin_types.entry_invalid;
10816 }10860 }
1081710861
10818 ConstExprValue *const_val = ir_resolve_const(ira, type_value, UndefBad);10862 return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, &type_value->value);
10819 if (!const_val)
10820 return ira->codegen->builtin_types.entry_invalid;
10821
10822 assert(const_val->data.x_type != nullptr);
10823 return const_val->data.x_type;
10824}10863}
1082510864
10826static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) {10865static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) {
...@@ -12500,26 +12539,22 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc...@@ -12500,26 +12539,22 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
12500 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst);12539 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst);
12501}12540}
1250212541
12503static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) {12542static bool ir_resolve_const_align(CodeGen *codegen, IrExecutable *exec, AstNode *source_node,
12504 if (type_is_invalid(value->value.type))12543 ConstExprValue *const_val, uint32_t *out)
12505 return false;12544{
1250612545 Error err;
12507 IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen));12546 if ((err = ir_resolve_const_val(codegen, exec, source_node, const_val, UndefBad)))
12508 if (type_is_invalid(casted_value->value.type))
12509 return false;
12510
12511 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad);
12512 if (!const_val)
12513 return false;12547 return false;
1251412548
12515 uint32_t align_bytes = bigint_as_unsigned(&const_val->data.x_bigint);12549 uint32_t align_bytes = bigint_as_unsigned(&const_val->data.x_bigint);
12516 if (align_bytes == 0) {12550 if (align_bytes == 0) {
12517 ir_add_error(ira, value, buf_sprintf("alignment must be >= 1"));12551 exec_add_error_node(codegen, exec, source_node, buf_sprintf("alignment must be >= 1"));
12518 return false;12552 return false;
12519 }12553 }
1252012554
12521 if (!is_power_of_2(align_bytes)) {12555 if (!is_power_of_2(align_bytes)) {
12522 ir_add_error(ira, value, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes));12556 exec_add_error_node(codegen, exec, source_node,
12557 buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes));
12523 return false;12558 return false;
12524 }12559 }
1252512560
...@@ -12527,6 +12562,18 @@ static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out...@@ -12527,6 +12562,18 @@ static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out
12527 return true;12562 return true;
12528}12563}
1252912564
12565static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) {
12566 if (type_is_invalid(value->value.type))
12567 return false;
12568
12569 IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen));
12570 if (type_is_invalid(casted_value->value.type))
12571 return false;
12572
12573 return ir_resolve_const_align(ira->codegen, ira->new_irb.exec, value->source_node,
12574 &casted_value->value, out);
12575}
12576
12530static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) {12577static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) {
12531 if (type_is_invalid(value->value.type))12578 if (type_is_invalid(value->value.type))
12532 return false;12579 return false;
...@@ -14151,7 +14198,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,...@@ -14151,7 +14198,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
14151 }14198 }
14152 }14199 }
1415314200
14154 switch (type_requires_comptime(ira->codegen, result_type)) {14201 switch (type_requires_comptime(ira->codegen, result_type, nullptr)) {
14155 case ReqCompTimeInvalid:14202 case ReqCompTimeInvalid:
14156 result_type = ira->codegen->builtin_types.entry_invalid;14203 result_type = ira->codegen->builtin_types.entry_invalid;
14157 break;14204 break;
...@@ -15113,7 +15160,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -15113,7 +15160,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
15113 }15160 }
1511415161
15115 if (!comptime_arg) {15162 if (!comptime_arg) {
15116 switch (type_requires_comptime(ira->codegen, casted_arg->value.type)) {15163 switch (type_requires_comptime(ira->codegen, casted_arg->value.type, nullptr)) {
15117 case ReqCompTimeYes:15164 case ReqCompTimeYes:
15118 ir_add_error(ira, casted_arg,15165 ir_add_error(ira, casted_arg,
15119 buf_sprintf("parameter of type '%s' requires comptime", buf_ptr(&casted_arg->value.type->name)));15166 buf_sprintf("parameter of type '%s' requires comptime", buf_ptr(&casted_arg->value.type->name)));
...@@ -15192,6 +15239,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,...@@ -15192,6 +15239,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
15192 case ConstValSpecialRuntime:15239 case ConstValSpecialRuntime:
15193 goto no_mem_slot;15240 goto no_mem_slot;
15194 case ConstValSpecialStatic: // fallthrough15241 case ConstValSpecialStatic: // fallthrough
15242 case ConstValSpecialLazy: // fallthrough
15195 case ConstValSpecialUndef: {15243 case ConstValSpecialUndef: {
15196 ConstPtrMut ptr_mut;15244 ConstPtrMut ptr_mut;
15197 if (comptime_var_mem) {15245 if (comptime_var_mem) {
...@@ -15313,7 +15361,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -15313,7 +15361,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
15313 }15361 }
15314 }15362 }
1531515363
15316 switch (type_requires_comptime(ira->codegen, child_type)) {15364 switch (type_requires_comptime(ira->codegen, child_type, nullptr)) {
15317 case ReqCompTimeInvalid:15365 case ReqCompTimeInvalid:
15318 return ira->codegen->invalid_instruction;15366 return ira->codegen->invalid_instruction;
15319 case ReqCompTimeYes:15367 case ReqCompTimeYes:
...@@ -15483,7 +15531,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15483,7 +15531,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15483 AstNode *body_node = fn_entry->body_node;15531 AstNode *body_node = fn_entry->body_node;
15484 result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type,15532 result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type,
15485 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry,15533 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry,
15486 nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node);15534 nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node, false);
1548715535
15488 if (inferred_err_set_type != nullptr) {15536 if (inferred_err_set_type != nullptr) {
15489 inferred_err_set_type->data.error_set.infer_fn = nullptr;15537 inferred_err_set_type->data.error_set.infer_fn = nullptr;
...@@ -15680,7 +15728,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15680,7 +15728,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15680 ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope,15728 ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope,
15681 fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen),15729 fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen),
15682 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota,15730 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota,
15683 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr);15731 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec,
15732 nullptr, false);
15684 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,15733 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
15685 impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr);15734 impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr);
15686 copy_const_val(&const_instruction->base.value, align_result, true);15735 copy_const_val(&const_instruction->base.value, align_result, true);
...@@ -15705,7 +15754,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15705,7 +15754,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15705 inst_fn_type_id.return_type = specified_return_type;15754 inst_fn_type_id.return_type = specified_return_type;
15706 }15755 }
1570715756
15708 switch (type_requires_comptime(ira->codegen, specified_return_type)) {15757 switch (type_requires_comptime(ira->codegen, specified_return_type, nullptr)) {
15709 case ReqCompTimeYes:15758 case ReqCompTimeYes:
15710 // Throw out our work and call the function as if it were comptime.15759 // Throw out our work and call the function as if it were comptime.
15711 return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr,15760 return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr,
...@@ -16512,7 +16561,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh...@@ -16512,7 +16561,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
16512 break;16561 break;
16513 }16562 }
1651416563
16515 switch (type_requires_comptime(ira->codegen, resolved_type)) {16564 switch (type_requires_comptime(ira->codegen, resolved_type, nullptr)) {
16516 case ReqCompTimeInvalid:16565 case ReqCompTimeInvalid:
16517 return ira->codegen->invalid_instruction;16566 return ira->codegen->invalid_instruction;
16518 case ReqCompTimeYes:16567 case ReqCompTimeYes:
...@@ -16960,7 +17009,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -16960,7 +17009,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
16960 }17009 }
16961 } else {17010 } else {
16962 // runtime known element index17011 // runtime known element index
16963 switch (type_requires_comptime(ira->codegen, return_type)) {17012 switch (type_requires_comptime(ira->codegen, return_type, nullptr)) {
16964 case ReqCompTimeYes:17013 case ReqCompTimeYes:
16965 ir_add_error(ira, elem_index,17014 ir_add_error(ira, elem_index,
16966 buf_sprintf("values of type '%s' must be comptime known, but index value is runtime known",17015 buf_sprintf("values of type '%s' must be comptime known, but index value is runtime known",
...@@ -17839,22 +17888,29 @@ static IrInstruction *ir_analyze_instruction_any_frame_type(IrAnalyze *ira,...@@ -17839,22 +17888,29 @@ static IrInstruction *ir_analyze_instruction_any_frame_type(IrAnalyze *ira,
17839static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,17888static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
17840 IrInstructionSliceType *slice_type_instruction)17889 IrInstructionSliceType *slice_type_instruction)
17841{17890{
17842 Error err;17891 IrInstruction *result = ir_const(ira, &slice_type_instruction->base, ira->codegen->builtin_types.entry_type);
17843 uint32_t align_bytes = 0;17892 result->value.special = ConstValSpecialLazy;
17893
17894 LazyValueSliceType *lazy_slice_type = allocate<LazyValueSliceType>(1);
17895 result->value.data.x_lazy = &lazy_slice_type->base;
17896 lazy_slice_type->base.id = LazyValueIdSliceType;
17897 lazy_slice_type->base.exec = ira->new_irb.exec;
17898
17844 if (slice_type_instruction->align_value != nullptr) {17899 if (slice_type_instruction->align_value != nullptr) {
17845 if (!ir_resolve_align(ira, slice_type_instruction->align_value->child, &align_bytes))17900 lazy_slice_type->align_val = ir_resolve_const(ira, slice_type_instruction->align_value->child, LazyOk);
17901 if (lazy_slice_type->align_val == nullptr)
17846 return ira->codegen->invalid_instruction;17902 return ira->codegen->invalid_instruction;
17847 }17903 }
1784817904
17849 ZigType *child_type = ir_resolve_type(ira, slice_type_instruction->child_type->child);17905 lazy_slice_type->elem_type = ir_resolve_type(ira, slice_type_instruction->child_type->child);
17850 if (type_is_invalid(child_type))17906 if (type_is_invalid(lazy_slice_type->elem_type))
17851 return ira->codegen->invalid_instruction;17907 return ira->codegen->invalid_instruction;
1785217908
17853 bool is_const = slice_type_instruction->is_const;17909 lazy_slice_type->is_const = slice_type_instruction->is_const;
17854 bool is_volatile = slice_type_instruction->is_volatile;17910 lazy_slice_type->is_volatile = slice_type_instruction->is_volatile;
17855 bool is_allow_zero = slice_type_instruction->is_allow_zero;17911 lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero;
1785617912
17857 switch (child_type->id) {17913 switch (lazy_slice_type->elem_type->id) {
17858 case ZigTypeIdInvalid: // handled above17914 case ZigTypeIdInvalid: // handled above
17859 zig_unreachable();17915 zig_unreachable();
17860 case ZigTypeIdUnreachable:17916 case ZigTypeIdUnreachable:
...@@ -17863,7 +17919,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -17863,7 +17919,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
17863 case ZigTypeIdArgTuple:17919 case ZigTypeIdArgTuple:
17864 case ZigTypeIdOpaque:17920 case ZigTypeIdOpaque:
17865 ir_add_error_node(ira, slice_type_instruction->base.source_node,17921 ir_add_error_node(ira, slice_type_instruction->base.source_node,
17866 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&child_type->name)));17922 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&lazy_slice_type->elem_type->name)));
17867 return ira->codegen->invalid_instruction;17923 return ira->codegen->invalid_instruction;
17868 case ZigTypeIdMetaType:17924 case ZigTypeIdMetaType:
17869 case ZigTypeIdVoid:17925 case ZigTypeIdVoid:
...@@ -17886,18 +17942,9 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -17886,18 +17942,9 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
17886 case ZigTypeIdVector:17942 case ZigTypeIdVector:
17887 case ZigTypeIdFnFrame:17943 case ZigTypeIdFnFrame:
17888 case ZigTypeIdAnyFrame:17944 case ZigTypeIdAnyFrame:
17889 {17945 break;
17890 ResolveStatus needed_status = (align_bytes == 0) ?
17891 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown;
17892 if ((err = type_resolve(ira->codegen, child_type, needed_status)))
17893 return ira->codegen->invalid_instruction;
17894 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type,
17895 is_const, is_volatile, PtrLenUnknown, align_bytes, 0, 0, is_allow_zero);
17896 ZigType *result_type = get_slice_type(ira->codegen, slice_ptr_type);
17897 return ir_const_type(ira, &slice_type_instruction->base, result_type);
17898 }
17899 }17946 }
17900 zig_unreachable();17947 return result;
17901}17948}
1790217949
17903static IrInstruction *ir_analyze_instruction_global_asm(IrAnalyze *ira, IrInstructionGlobalAsm *instruction) {17950static IrInstruction *ir_analyze_instruction_global_asm(IrAnalyze *ira, IrInstructionGlobalAsm *instruction) {
...@@ -18947,7 +18994,7 @@ static IrInstruction *ir_analyze_union_init(IrAnalyze *ira, IrInstruction *sourc...@@ -18947,7 +18994,7 @@ static IrInstruction *ir_analyze_union_init(IrAnalyze *ira, IrInstruction *sourc
18947 }18994 }
1894818995
18949 bool is_comptime = ir_should_inline(ira->new_irb.exec, source_instruction->scope)18996 bool is_comptime = ir_should_inline(ira->new_irb.exec, source_instruction->scope)
18950 || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes;18997 || type_requires_comptime(ira->codegen, union_type, nullptr) == ReqCompTimeYes;
1895118998
18952 IrInstruction *result = ir_get_deref(ira, source_instruction, result_loc, nullptr);18999 IrInstruction *result = ir_get_deref(ira, source_instruction, result_loc, nullptr);
18953 if (is_comptime && !instr_is_comptime(result)) {19000 if (is_comptime && !instr_is_comptime(result)) {
...@@ -18995,7 +19042,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -18995,7 +19042,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
18995 ZigList<IrInstruction *> const_ptrs = {};19042 ZigList<IrInstruction *> const_ptrs = {};
1899619043
18997 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope)19044 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope)
18998 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;19045 || type_requires_comptime(ira->codegen, container_type, nullptr) == ReqCompTimeYes;
1899919046
1900019047
19001 // Here we iterate over the fields that have been initialized, and emit19048 // Here we iterate over the fields that have been initialized, and emit
...@@ -19173,7 +19220,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -19173,7 +19220,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
19173 }19220 }
1917419221
19175 bool is_comptime;19222 bool is_comptime;
19176 switch (type_requires_comptime(ira->codegen, container_type)) {19223 switch (type_requires_comptime(ira->codegen, container_type, nullptr)) {
19177 case ReqCompTimeInvalid:19224 case ReqCompTimeInvalid:
19178 return ira->codegen->invalid_instruction;19225 return ira->codegen->invalid_instruction;
19179 case ReqCompTimeNo:19226 case ReqCompTimeNo:
...@@ -20575,7 +20622,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct...@@ -20575,7 +20622,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
20575 ZigType *void_type = ira->codegen->builtin_types.entry_void;20622 ZigType *void_type = ira->codegen->builtin_types.entry_void;
20576 ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type,20623 ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type,
20577 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr,20624 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr,
20578 &cimport_scope->buf, block_node, nullptr, nullptr, nullptr);20625 &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, false);
20579 if (type_is_invalid(cimport_result->type))20626 if (type_is_invalid(cimport_result->type))
20580 return ira->codegen->invalid_instruction;20627 return ira->codegen->invalid_instruction;
2058120628
...@@ -22243,15 +22290,11 @@ static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstru...@@ -22243,15 +22290,11 @@ static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstru
22243}22290}
2224422291
22245static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) {22292static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) {
22246 Error err;
22247 IrInstruction *type_value = instruction->type_value->child;22293 IrInstruction *type_value = instruction->type_value->child;
22248 if (type_is_invalid(type_value->value.type))22294 if (type_is_invalid(type_value->value.type))
22249 return ira->codegen->invalid_instruction;22295 return ira->codegen->invalid_instruction;
22250 ZigType *type_entry = ir_resolve_type(ira, type_value);22296 ZigType *type_entry = ir_resolve_type(ira, type_value);
2225122297
22252 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusAlignmentKnown)))
22253 return ira->codegen->invalid_instruction;
22254
22255 switch (type_entry->id) {22298 switch (type_entry->id) {
22256 case ZigTypeIdInvalid:22299 case ZigTypeIdInvalid:
22257 zig_unreachable();22300 zig_unreachable();
...@@ -22284,12 +22327,27 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct...@@ -22284,12 +22327,27 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct
22284 case ZigTypeIdVector:22327 case ZigTypeIdVector:
22285 case ZigTypeIdFnFrame:22328 case ZigTypeIdFnFrame:
22286 case ZigTypeIdAnyFrame:22329 case ZigTypeIdAnyFrame:
22287 {22330 break;
22288 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);
22289 return ir_const_unsigned(ira, &instruction->base, align_in_bytes);
22290 }
22291 }22331 }
22292 zig_unreachable();22332
22333 if (type_is_resolved(type_entry, ResolveStatusAlignmentKnown)) {
22334 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);
22335 return ir_const_unsigned(ira, &instruction->base, align_in_bytes);
22336 }
22337
22338 // Here we create a lazy value in order to avoid resolving the alignment of the type
22339 // immediately. This avoids false positive dependency loops such as:
22340 // const Node = struct {
22341 // field: []align(@alignOf(Node)) Node,
22342 // };
22343 LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1);
22344 lazy_align_of->base.id = LazyValueIdAlignOf;
22345 lazy_align_of->base.exec = ira->new_irb.exec;
22346 lazy_align_of->target_type = type_entry;
22347 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int);
22348 result->value.special = ConstValSpecialLazy;
22349 result->value.data.x_lazy = &lazy_align_of->base;
22350 return result;
22293}22351}
2229422352
22295static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) {22353static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) {
...@@ -22783,7 +22841,7 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct...@@ -22783,7 +22841,7 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct
22783 if (type_is_invalid(param_type_value->value.type))22841 if (type_is_invalid(param_type_value->value.type))
22784 return ira->codegen->invalid_instruction;22842 return ira->codegen->invalid_instruction;
22785 ZigType *param_type = ir_resolve_type(ira, param_type_value);22843 ZigType *param_type = ir_resolve_type(ira, param_type_value);
22786 switch (type_requires_comptime(ira->codegen, param_type)) {22844 switch (type_requires_comptime(ira->codegen, param_type, nullptr)) {
22787 case ReqCompTimeYes:22845 case ReqCompTimeYes:
22788 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {22846 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
22789 ir_add_error(ira, param_type_value,22847 ir_add_error(ira, param_type_value,
...@@ -23792,10 +23850,18 @@ static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstru...@@ -23792,10 +23850,18 @@ static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstru
23792}23850}
2379323851
23794static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) {23852static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) {
23795 Error err;23853 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type);
23854 result->value.special = ConstValSpecialLazy;
23855
23856 LazyValuePtrType *lazy_ptr_type = allocate<LazyValuePtrType>(1);
23857 result->value.data.x_lazy = &lazy_ptr_type->base;
23858 lazy_ptr_type->base.id = LazyValueIdPtrType;
23859 lazy_ptr_type->base.exec = ira->new_irb.exec;
23860
23796 ZigType *child_type = ir_resolve_type(ira, instruction->child_type->child);23861 ZigType *child_type = ir_resolve_type(ira, instruction->child_type->child);
23797 if (type_is_invalid(child_type))23862 if (type_is_invalid(child_type))
23798 return ira->codegen->invalid_instruction;23863 return ira->codegen->invalid_instruction;
23864 lazy_ptr_type->elem_type = child_type;
2379923865
23800 if (child_type->id == ZigTypeIdUnreachable) {23866 if (child_type->id == ZigTypeIdUnreachable) {
23801 ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed"));23867 ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed"));
...@@ -23817,28 +23883,20 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct...@@ -23817,28 +23883,20 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct
23817 }23883 }
23818 }23884 }
2381923885
23820 uint32_t align_bytes;
23821 if (instruction->align_value != nullptr) {23886 if (instruction->align_value != nullptr) {
23822 if (!ir_resolve_align(ira, instruction->align_value->child, &align_bytes))23887 lazy_ptr_type->align_val = ir_resolve_const(ira, instruction->align_value->child, LazyOk);
23823 return ira->codegen->invalid_instruction;23888 if (lazy_ptr_type->align_val == nullptr)
23824 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusAlignmentKnown)))
23825 return ira->codegen->invalid_instruction;
23826 if (!type_has_bits(child_type)) {
23827 align_bytes = 0;
23828 }
23829 } else {
23830 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown)))
23831 return ira->codegen->invalid_instruction;23889 return ira->codegen->invalid_instruction;
23832 align_bytes = 0;
23833 }23890 }
2383423891
23835 bool allow_zero = instruction->is_allow_zero || instruction->ptr_len == PtrLenC;23892 lazy_ptr_type->ptr_len = instruction->ptr_len;
23893 lazy_ptr_type->is_const = instruction->is_const;
23894 lazy_ptr_type->is_volatile = instruction->is_volatile;
23895 lazy_ptr_type->is_allowzero = instruction->is_allow_zero;
23896 lazy_ptr_type->bit_offset_in_host = instruction->bit_offset_start;
23897 lazy_ptr_type->host_int_bytes = instruction->host_int_bytes;
2383623898
23837 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type,23899 return result;
23838 instruction->is_const, instruction->is_volatile,
23839 instruction->ptr_len, align_bytes,
23840 instruction->bit_offset_start, instruction->host_int_bytes, allow_zero);
23841 return ir_const_type(ira, &instruction->base, result_type);
23842}23900}
2384323901
23844static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstructionAlignCast *instruction) {23902static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstructionAlignCast *instruction) {
...@@ -25365,3 +25423,66 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -25365,3 +25423,66 @@ bool ir_has_side_effects(IrInstruction *instruction) {
25365 }25423 }
25366 zig_unreachable();25424 zig_unreachable();
25367}25425}
25426
25427Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) {
25428 Error err;
25429 if (val->special != ConstValSpecialLazy)
25430 return ErrorNone;
25431 IrExecutable *exec = val->data.x_lazy->exec;
25432 switch (val->data.x_lazy->id) {
25433 case LazyValueIdInvalid:
25434 zig_unreachable();
25435 case LazyValueIdAlignOf: {
25436 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy);
25437 if ((err = type_resolve(codegen, lazy_align_of->target_type, ResolveStatusAlignmentKnown)))
25438 return err;
25439 uint64_t align_in_bytes = get_abi_alignment(codegen, lazy_align_of->target_type);
25440 val->special = ConstValSpecialStatic;
25441 assert(val->type->id == ZigTypeIdComptimeInt);
25442 bigint_init_unsigned(&val->data.x_bigint, align_in_bytes);
25443 return ErrorNone;
25444 }
25445 case LazyValueIdSliceType: {
25446 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy);
25447 uint32_t align_bytes = 0;
25448 if (lazy_slice_type->align_val != nullptr) {
25449 if (!ir_resolve_const_align(codegen, exec, source_node, lazy_slice_type->align_val, &align_bytes))
25450 return ErrorSemanticAnalyzeFail;
25451 }
25452 ResolveStatus needed_status = (align_bytes == 0) ?
25453 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown;
25454 if ((err = type_resolve(codegen, lazy_slice_type->elem_type, needed_status)))
25455 return err;
25456 ZigType *slice_ptr_type = get_pointer_to_type_extra(codegen, lazy_slice_type->elem_type,
25457 lazy_slice_type->is_const, lazy_slice_type->is_volatile, PtrLenUnknown, align_bytes,
25458 0, 0, lazy_slice_type->is_allowzero);
25459 val->special = ConstValSpecialStatic;
25460 assert(val->type->id == ZigTypeIdMetaType);
25461 val->data.x_type = get_slice_type(codegen, slice_ptr_type);
25462 return ErrorNone;
25463 }
25464 case LazyValueIdPtrType: {
25465 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(val->data.x_lazy);
25466 uint32_t align_bytes = 0;
25467 if (lazy_ptr_type->align_val != nullptr) {
25468 if (!ir_resolve_const_align(codegen, exec, source_node, lazy_ptr_type->align_val, &align_bytes))
25469 return ErrorSemanticAnalyzeFail;
25470 }
25471 ResolveStatus needed_status = (align_bytes == 0) ?
25472 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown;
25473 if ((err = type_resolve(codegen, lazy_ptr_type->elem_type, needed_status)))
25474 return err;
25475 if (!type_has_bits(lazy_ptr_type->elem_type))
25476 align_bytes = 0;
25477 bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC;
25478 assert(val->type->id == ZigTypeIdMetaType);
25479 val->data.x_type = get_pointer_to_type_extra(codegen, lazy_ptr_type->elem_type,
25480 lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes,
25481 lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes,
25482 allow_zero);
25483 val->special = ConstValSpecialStatic;
25484 return ErrorNone;
25485 }
25486 }
25487 zig_unreachable();
25488}
src/ir.hpp+3-1
...@@ -16,7 +16,9 @@ bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry);...@@ -16,7 +16,9 @@ bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry);
16ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,16ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
17 ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota,17 ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota,
18 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,18 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
19 IrExecutable *parent_exec, AstNode *expected_type_source_node);19 IrExecutable *parent_exec, AstNode *expected_type_source_node, bool allow_lazy);
20
21Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val);
2022
21ZigType *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable,23ZigType *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable,
22 ZigType *expected_type, AstNode *expected_type_source_node);24 ZigType *expected_type, AstNode *expected_type_source_node);