| author | |
| committer | |
| log | 35a374efe034ae5ed9aafc06bbc581044e7325de |
| tree | 41f0fdd7555532dab92e38fb8afc58aa96ccdf61 |
| parent | 326b7b794b01a1194df3785e497460bada756c29 |
| parent | d9ed55f017bdd23054cd1d7f50ac1da517b5a5e4 |
| signature |
fix field alignment kludge by implementing lazy values11 files changed, 1796 insertions(+), 1061 deletions(-)
src/all_types.hpp+106-31| ... | @@ -47,6 +47,19 @@ struct ResultLocPeer; | ... | @@ -47,6 +47,19 @@ struct ResultLocPeer; |
| 47 | struct ResultLocPeerParent; | 47 | struct ResultLocPeerParent; |
| 48 | struct ResultLocBitCast; | 48 | struct ResultLocBitCast; |
| 49 | 49 | ||
| 50 | enum PtrLen { | ||
| 51 | PtrLenUnknown, | ||
| 52 | PtrLenSingle, | ||
| 53 | PtrLenC, | ||
| 54 | }; | ||
| 55 | |||
| 56 | enum UndefAllowed { | ||
| 57 | UndefOk, | ||
| 58 | UndefBad, | ||
| 59 | LazyOkNoUndef, | ||
| 60 | LazyOk, | ||
| 61 | }; | ||
| 62 | |||
| 50 | enum X64CABIClass { | 63 | enum X64CABIClass { |
| 51 | X64CABIClass_Unknown, | 64 | X64CABIClass_Unknown, |
| 52 | X64CABIClass_MEMORY, | 65 | X64CABIClass_MEMORY, |
| ... | @@ -69,9 +82,9 @@ struct IrExecutable { | ... | @@ -69,9 +82,9 @@ struct IrExecutable { |
| 69 | IrExecutable *source_exec; | 82 | IrExecutable *source_exec; |
| 70 | IrAnalyze *analysis; | 83 | IrAnalyze *analysis; |
| 71 | Scope *begin_scope; | 84 | Scope *begin_scope; |
| 85 | ErrorMsg *first_err_trace_msg; | ||
| 72 | ZigList<Tld *> tld_list; | 86 | ZigList<Tld *> tld_list; |
| 73 | 87 | ||
| 74 | bool invalid; | ||
| 75 | bool is_inline; | 88 | bool is_inline; |
| 76 | bool is_generic_instantiation; | 89 | bool is_generic_instantiation; |
| 77 | bool need_err_code_spill; | 90 | bool need_err_code_spill; |
| ... | @@ -255,6 +268,7 @@ enum ConstValSpecial { | ... | @@ -255,6 +268,7 @@ enum ConstValSpecial { |
| 255 | ConstValSpecialRuntime, | 268 | ConstValSpecialRuntime, |
| 256 | ConstValSpecialStatic, | 269 | ConstValSpecialStatic, |
| 257 | ConstValSpecialUndef, | 270 | ConstValSpecialUndef, |
| 271 | ConstValSpecialLazy, | ||
| 258 | }; | 272 | }; |
| 259 | 273 | ||
| 260 | enum RuntimeHintErrorUnion { | 274 | enum RuntimeHintErrorUnion { |
| ... | @@ -291,6 +305,73 @@ struct ConstGlobalRefs { | ... | @@ -291,6 +305,73 @@ struct ConstGlobalRefs { |
| 291 | uint32_t align; | 305 | uint32_t align; |
| 292 | }; | 306 | }; |
| 293 | 307 | ||
| 308 | enum LazyValueId { | ||
| 309 | LazyValueIdInvalid, | ||
| 310 | LazyValueIdAlignOf, | ||
| 311 | LazyValueIdPtrType, | ||
| 312 | LazyValueIdOptType, | ||
| 313 | LazyValueIdSliceType, | ||
| 314 | LazyValueIdFnType, | ||
| 315 | }; | ||
| 316 | |||
| 317 | struct LazyValue { | ||
| 318 | LazyValueId id; | ||
| 319 | }; | ||
| 320 | |||
| 321 | struct LazyValueAlignOf { | ||
| 322 | LazyValue base; | ||
| 323 | |||
| 324 | IrAnalyze *ira; | ||
| 325 | IrInstruction *target_type; | ||
| 326 | }; | ||
| 327 | |||
| 328 | struct LazyValueSliceType { | ||
| 329 | LazyValue base; | ||
| 330 | |||
| 331 | IrAnalyze *ira; | ||
| 332 | ZigType *elem_type; | ||
| 333 | IrInstruction *align_inst; // can be null | ||
| 334 | |||
| 335 | bool is_const; | ||
| 336 | bool is_volatile; | ||
| 337 | bool is_allowzero; | ||
| 338 | }; | ||
| 339 | |||
| 340 | struct LazyValuePtrType { | ||
| 341 | LazyValue base; | ||
| 342 | |||
| 343 | IrAnalyze *ira; | ||
| 344 | IrInstruction *elem_type; | ||
| 345 | IrInstruction *align_inst; // can be null | ||
| 346 | |||
| 347 | PtrLen ptr_len; | ||
| 348 | uint32_t bit_offset_in_host; | ||
| 349 | |||
| 350 | uint32_t host_int_bytes; | ||
| 351 | bool is_const; | ||
| 352 | bool is_volatile; | ||
| 353 | bool is_allowzero; | ||
| 354 | }; | ||
| 355 | |||
| 356 | struct LazyValueOptType { | ||
| 357 | LazyValue base; | ||
| 358 | |||
| 359 | IrAnalyze *ira; | ||
| 360 | IrInstruction *payload_type; | ||
| 361 | }; | ||
| 362 | |||
| 363 | struct LazyValueFnType { | ||
| 364 | LazyValue base; | ||
| 365 | |||
| 366 | IrAnalyze *ira; | ||
| 367 | AstNode *proto_node; | ||
| 368 | IrInstruction **param_types; | ||
| 369 | IrInstruction *align_inst; // can be null | ||
| 370 | IrInstruction *return_type; | ||
| 371 | |||
| 372 | bool is_generic; | ||
| 373 | }; | ||
| 374 | |||
| 294 | struct ConstExprValue { | 375 | struct ConstExprValue { |
| 295 | ZigType *type; | 376 | ZigType *type; |
| 296 | ConstValSpecial special; | 377 | ConstValSpecial special; |
| ... | @@ -318,6 +399,7 @@ struct ConstExprValue { | ... | @@ -318,6 +399,7 @@ struct ConstExprValue { |
| 318 | ConstPtrValue x_ptr; | 399 | ConstPtrValue x_ptr; |
| 319 | ConstArgTuple x_arg_tuple; | 400 | ConstArgTuple x_arg_tuple; |
| 320 | Buf *x_enum_literal; | 401 | Buf *x_enum_literal; |
| 402 | LazyValue *x_lazy; | ||
| 321 | 403 | ||
| 322 | // populated if special == ConstValSpecialRuntime | 404 | // populated if special == ConstValSpecialRuntime |
| 323 | RuntimeHintErrorUnion rh_error_union; | 405 | RuntimeHintErrorUnion rh_error_union; |
| ... | @@ -364,6 +446,7 @@ enum TldResolution { | ... | @@ -364,6 +446,7 @@ enum TldResolution { |
| 364 | TldResolutionUnresolved, | 446 | TldResolutionUnresolved, |
| 365 | TldResolutionResolving, | 447 | TldResolutionResolving, |
| 366 | TldResolutionInvalid, | 448 | TldResolutionInvalid, |
| 449 | TldResolutionOkLazy, | ||
| 367 | TldResolutionOk, | 450 | TldResolutionOk, |
| 368 | }; | 451 | }; |
| 369 | 452 | ||
| ... | @@ -420,10 +503,12 @@ struct TypeEnumField { | ... | @@ -420,10 +503,12 @@ struct TypeEnumField { |
| 420 | 503 | ||
| 421 | struct TypeUnionField { | 504 | struct TypeUnionField { |
| 422 | Buf *name; | 505 | Buf *name; |
| 506 | ZigType *type_entry; // available after ResolveStatusSizeKnown | ||
| 507 | ConstExprValue *type_val; // available after ResolveStatusZeroBitsKnown | ||
| 423 | TypeEnumField *enum_field; | 508 | TypeEnumField *enum_field; |
| 424 | ZigType *type_entry; | ||
| 425 | AstNode *decl_node; | 509 | AstNode *decl_node; |
| 426 | uint32_t gen_index; | 510 | uint32_t gen_index; |
| 511 | uint32_t align; | ||
| 427 | }; | 512 | }; |
| 428 | 513 | ||
| 429 | enum NodeType { | 514 | enum NodeType { |
| ... | @@ -946,6 +1031,7 @@ struct AstNodeEnumLiteral { | ... | @@ -946,6 +1031,7 @@ struct AstNodeEnumLiteral { |
| 946 | 1031 | ||
| 947 | struct AstNode { | 1032 | struct AstNode { |
| 948 | enum NodeType type; | 1033 | enum NodeType type; |
| 1034 | bool already_traced_this_node; | ||
| 949 | size_t line; | 1035 | size_t line; |
| 950 | size_t column; | 1036 | size_t column; |
| 951 | ZigType *owner; | 1037 | ZigType *owner; |
| ... | @@ -1041,12 +1127,6 @@ struct FnTypeId { | ... | @@ -1041,12 +1127,6 @@ struct FnTypeId { |
| 1041 | uint32_t fn_type_id_hash(FnTypeId*); | 1127 | uint32_t fn_type_id_hash(FnTypeId*); |
| 1042 | bool fn_type_id_eql(FnTypeId *a, FnTypeId *b); | 1128 | bool fn_type_id_eql(FnTypeId *a, FnTypeId *b); |
| 1043 | 1129 | ||
| 1044 | enum PtrLen { | ||
| 1045 | PtrLenUnknown, | ||
| 1046 | PtrLenSingle, | ||
| 1047 | PtrLenC, | ||
| 1048 | }; | ||
| 1049 | |||
| 1050 | struct ZigTypePointer { | 1130 | struct ZigTypePointer { |
| 1051 | ZigType *child_type; | 1131 | ZigType *child_type; |
| 1052 | ZigType *slice_parent; | 1132 | ZigType *slice_parent; |
| ... | @@ -1057,6 +1137,7 @@ struct ZigTypePointer { | ... | @@ -1057,6 +1137,7 @@ struct ZigTypePointer { |
| 1057 | bool is_const; | 1137 | bool is_const; |
| 1058 | bool is_volatile; | 1138 | bool is_volatile; |
| 1059 | bool allow_zero; | 1139 | bool allow_zero; |
| 1140 | bool resolve_loop_flag_zero_bits; | ||
| 1060 | }; | 1141 | }; |
| 1061 | 1142 | ||
| 1062 | struct ZigTypeInt { | 1143 | struct ZigTypeInt { |
| ... | @@ -1075,7 +1156,8 @@ struct ZigTypeArray { | ... | @@ -1075,7 +1156,8 @@ struct ZigTypeArray { |
| 1075 | 1156 | ||
| 1076 | struct TypeStructField { | 1157 | struct TypeStructField { |
| 1077 | Buf *name; | 1158 | Buf *name; |
| 1078 | ZigType *type_entry; | 1159 | ZigType *type_entry; // available after ResolveStatusSizeKnown |
| 1160 | ConstExprValue *type_val; // available after ResolveStatusZeroBitsKnown | ||
| 1079 | size_t src_index; | 1161 | size_t src_index; |
| 1080 | size_t gen_index; | 1162 | size_t gen_index; |
| 1081 | size_t offset; // byte offset from beginning of struct | 1163 | size_t offset; // byte offset from beginning of struct |
| ... | @@ -1131,11 +1213,11 @@ struct ZigTypeStruct { | ... | @@ -1131,11 +1213,11 @@ struct ZigTypeStruct { |
| 1131 | ResolveStatus resolve_status; | 1213 | ResolveStatus resolve_status; |
| 1132 | 1214 | ||
| 1133 | bool is_slice; | 1215 | bool is_slice; |
| 1134 | bool resolve_loop_flag; // set this flag temporarily to detect infinite loops | ||
| 1135 | bool reported_infinite_err; | ||
| 1136 | // whether any of the fields require comptime | 1216 | // whether any of the fields require comptime |
| 1137 | // known after ResolveStatusZeroBitsKnown | 1217 | // known after ResolveStatusZeroBitsKnown |
| 1138 | bool requires_comptime; | 1218 | bool requires_comptime; |
| 1219 | bool resolve_loop_flag_zero_bits; | ||
| 1220 | bool resolve_loop_flag_other; | ||
| 1139 | }; | 1221 | }; |
| 1140 | 1222 | ||
| 1141 | struct ZigTypeOptional { | 1223 | struct ZigTypeOptional { |
| ... | @@ -1157,26 +1239,20 @@ struct ZigTypeErrorSet { | ... | @@ -1157,26 +1239,20 @@ struct ZigTypeErrorSet { |
| 1157 | 1239 | ||
| 1158 | struct ZigTypeEnum { | 1240 | struct ZigTypeEnum { |
| 1159 | AstNode *decl_node; | 1241 | AstNode *decl_node; |
| 1160 | ContainerLayout layout; | ||
| 1161 | uint32_t src_field_count; | ||
| 1162 | TypeEnumField *fields; | 1242 | TypeEnumField *fields; |
| 1163 | bool is_invalid; // true if any fields are invalid | ||
| 1164 | ZigType *tag_int_type; | 1243 | ZigType *tag_int_type; |
| 1165 | 1244 | ||
| 1166 | ScopeDecls *decls_scope; | 1245 | ScopeDecls *decls_scope; |
| 1167 | 1246 | ||
| 1168 | // set this flag temporarily to detect infinite loops | ||
| 1169 | bool embedded_in_current; | ||
| 1170 | bool reported_infinite_err; | ||
| 1171 | // whether we've finished resolving it | ||
| 1172 | bool complete; | ||
| 1173 | |||
| 1174 | bool zero_bits_loop_flag; | ||
| 1175 | bool zero_bits_known; | ||
| 1176 | |||
| 1177 | LLVMValueRef name_function; | 1247 | LLVMValueRef name_function; |
| 1178 | 1248 | ||
| 1179 | HashMap<Buf *, TypeEnumField *, buf_hash, buf_eql_buf> fields_by_name; | 1249 | HashMap<Buf *, TypeEnumField *, buf_hash, buf_eql_buf> fields_by_name; |
| 1250 | uint32_t src_field_count; | ||
| 1251 | |||
| 1252 | ContainerLayout layout; | ||
| 1253 | ResolveStatus resolve_status; | ||
| 1254 | |||
| 1255 | bool resolve_loop_flag; | ||
| 1180 | }; | 1256 | }; |
| 1181 | 1257 | ||
| 1182 | uint32_t type_ptr_hash(const ZigType *ptr); | 1258 | uint32_t type_ptr_hash(const ZigType *ptr); |
| ... | @@ -1189,7 +1265,7 @@ struct ZigTypeUnion { | ... | @@ -1189,7 +1265,7 @@ struct ZigTypeUnion { |
| 1189 | HashMap<Buf *, TypeUnionField *, buf_hash, buf_eql_buf> fields_by_name; | 1265 | HashMap<Buf *, TypeUnionField *, buf_hash, buf_eql_buf> fields_by_name; |
| 1190 | ZigType *tag_type; // always an enum or null | 1266 | ZigType *tag_type; // always an enum or null |
| 1191 | LLVMTypeRef union_llvm_type; | 1267 | LLVMTypeRef union_llvm_type; |
| 1192 | ZigType *most_aligned_union_member; | 1268 | TypeUnionField *most_aligned_union_member; |
| 1193 | size_t gen_union_index; | 1269 | size_t gen_union_index; |
| 1194 | size_t gen_tag_index; | 1270 | size_t gen_tag_index; |
| 1195 | size_t union_abi_size; | 1271 | size_t union_abi_size; |
| ... | @@ -1201,11 +1277,11 @@ struct ZigTypeUnion { | ... | @@ -1201,11 +1277,11 @@ struct ZigTypeUnion { |
| 1201 | ResolveStatus resolve_status; | 1277 | ResolveStatus resolve_status; |
| 1202 | 1278 | ||
| 1203 | bool have_explicit_tag_type; | 1279 | bool have_explicit_tag_type; |
| 1204 | bool resolve_loop_flag; // set this flag temporarily to detect infinite loops | ||
| 1205 | bool reported_infinite_err; | ||
| 1206 | // whether any of the fields require comptime | 1280 | // whether any of the fields require comptime |
| 1207 | // the value is not valid until zero_bits_known == true | 1281 | // the value is not valid until zero_bits_known == true |
| 1208 | bool requires_comptime; | 1282 | bool requires_comptime; |
| 1283 | bool resolve_loop_flag_zero_bits; | ||
| 1284 | bool resolve_loop_flag_other; | ||
| 1209 | }; | 1285 | }; |
| 1210 | 1286 | ||
| 1211 | struct FnGenParamInfo { | 1287 | struct FnGenParamInfo { |
| ... | @@ -1717,6 +1793,7 @@ struct CodeGen { | ... | @@ -1717,6 +1793,7 @@ struct CodeGen { |
| 1717 | //////////////////////////// Runtime State | 1793 | //////////////////////////// Runtime State |
| 1718 | LLVMModuleRef module; | 1794 | LLVMModuleRef module; |
| 1719 | ZigList<ErrorMsg*> errors; | 1795 | ZigList<ErrorMsg*> errors; |
| 1796 | ErrorMsg *trace_err; | ||
| 1720 | LLVMBuilderRef builder; | 1797 | LLVMBuilderRef builder; |
| 1721 | ZigLLVMDIBuilder *dbuilder; | 1798 | ZigLLVMDIBuilder *dbuilder; |
| 1722 | ZigLLVMDICompileUnit *compile_unit; | 1799 | ZigLLVMDICompileUnit *compile_unit; |
| ... | @@ -1769,7 +1846,6 @@ struct CodeGen { | ... | @@ -1769,7 +1846,6 @@ struct CodeGen { |
| 1769 | ZigList<Tld *> resolve_queue; | 1846 | ZigList<Tld *> resolve_queue; |
| 1770 | size_t resolve_queue_index; | 1847 | size_t resolve_queue_index; |
| 1771 | ZigList<TimeEvent> timing_events; | 1848 | ZigList<TimeEvent> timing_events; |
| 1772 | ZigList<AstNode *> tld_ref_source_node_stack; | ||
| 1773 | ZigList<ZigFn *> inline_fns; | 1849 | ZigList<ZigFn *> inline_fns; |
| 1774 | ZigList<ZigFn *> test_fns; | 1850 | ZigList<ZigFn *> test_fns; |
| 1775 | ZigList<ErrorTableEntry *> errors_by_index; | 1851 | ZigList<ErrorTableEntry *> errors_by_index; |
| ... | @@ -1854,7 +1930,6 @@ struct CodeGen { | ... | @@ -1854,7 +1930,6 @@ struct CodeGen { |
| 1854 | ZigFn *main_fn; | 1930 | ZigFn *main_fn; |
| 1855 | ZigFn *panic_fn; | 1931 | ZigFn *panic_fn; |
| 1856 | TldFn *panic_tld_fn; | 1932 | TldFn *panic_tld_fn; |
| 1857 | AstNode *root_export_decl; | ||
| 1858 | 1933 | ||
| 1859 | WantPIC want_pic; | 1934 | WantPIC want_pic; |
| 1860 | WantStackCheck want_stack_check; | 1935 | WantStackCheck want_stack_check; |
| ... | @@ -1942,7 +2017,7 @@ struct CodeGen { | ... | @@ -1942,7 +2017,7 @@ struct CodeGen { |
| 1942 | Buf *zig_lib_dir; | 2017 | Buf *zig_lib_dir; |
| 1943 | Buf *zig_std_dir; | 2018 | Buf *zig_std_dir; |
| 1944 | Buf *dynamic_linker_path; | 2019 | Buf *dynamic_linker_path; |
| 1945 | Buf *version_script_path; | 2020 | Buf *version_script_path; |
| 1946 | 2021 | ||
| 1947 | const char **llvm_argv; | 2022 | const char **llvm_argv; |
| 1948 | size_t llvm_argv_len; | 2023 | size_t llvm_argv_len; |
| ... | @@ -3659,13 +3734,13 @@ enum ResultLocId { | ... | @@ -3659,13 +3734,13 @@ enum ResultLocId { |
| 3659 | ResultLocIdBitCast, | 3734 | ResultLocIdBitCast, |
| 3660 | }; | 3735 | }; |
| 3661 | 3736 | ||
| 3662 | // Additions to this struct may need to be handled in | 3737 | // Additions to this struct may need to be handled in |
| 3663 | // ir_reset_result | 3738 | // ir_reset_result |
| 3664 | struct ResultLoc { | 3739 | struct ResultLoc { |
| 3665 | ResultLocId id; | 3740 | ResultLocId id; |
| 3666 | bool written; | 3741 | bool written; |
| 3667 | bool allow_write_through_const; | 3742 | bool allow_write_through_const; |
| 3668 | IrInstruction *resolved_loc; // result ptr | 3743 | IrInstruction *resolved_loc; // result ptr |
| 3669 | IrInstruction *source_instruction; | 3744 | IrInstruction *source_instruction; |
| 3670 | IrInstruction *gen_instruction; // value to store to the result loc | 3745 | IrInstruction *gen_instruction; // value to store to the result loc |
| 3671 | ZigType *implicit_elem_type; | 3746 | ZigType *implicit_elem_type; |
src/analyze.cpp+698-455| ... | @@ -20,7 +20,7 @@ | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | ||
| 21 | static const size_t default_backward_branch_quota = 1000; | 21 | static const size_t default_backward_branch_quota = 1000; |
| 22 | 22 | ||
| 23 | static Error resolve_struct_type(CodeGen *g, ZigType *struct_type); | 23 | static Error ATTRIBUTE_MUST_USE resolve_struct_type(CodeGen *g, ZigType *struct_type); |
| 24 | 24 | ||
| 25 | static Error ATTRIBUTE_MUST_USE resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type); | 25 | static Error ATTRIBUTE_MUST_USE resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type); |
| 26 | static Error ATTRIBUTE_MUST_USE resolve_struct_alignment(CodeGen *g, ZigType *struct_type); | 26 | static Error ATTRIBUTE_MUST_USE resolve_struct_alignment(CodeGen *g, ZigType *struct_type); |
| ... | @@ -59,13 +59,15 @@ ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg) { | ... | @@ -59,13 +59,15 @@ ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg) { |
| 59 | root_struct->source_code, root_struct->line_offsets, msg); | 59 | root_struct->source_code, root_struct->line_offsets, msg); |
| 60 | 60 | ||
| 61 | g->errors.append(err); | 61 | g->errors.append(err); |
| 62 | g->trace_err = err; | ||
| 62 | return err; | 63 | return err; |
| 63 | } | 64 | } |
| 64 | 65 | ||
| 65 | ErrorMsg *add_node_error(CodeGen *g, const AstNode *node, Buf *msg) { | 66 | ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) { |
| 66 | Token fake_token; | 67 | Token fake_token; |
| 67 | fake_token.start_line = node->line; | 68 | fake_token.start_line = node->line; |
| 68 | fake_token.start_column = node->column; | 69 | fake_token.start_column = node->column; |
| 70 | node->already_traced_this_node = true; | ||
| 69 | return add_token_error(g, node->owner, &fake_token, msg); | 71 | return add_token_error(g, node->owner, &fake_token, msg); |
| 70 | } | 72 | } |
| 71 | 73 | ||
| ... | @@ -271,6 +273,8 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) { | ... | @@ -271,6 +273,8 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) { |
| 271 | return type_entry->data.structure.resolve_status >= status; | 273 | return type_entry->data.structure.resolve_status >= status; |
| 272 | case ZigTypeIdUnion: | 274 | case ZigTypeIdUnion: |
| 273 | return type_entry->data.unionation.resolve_status >= status; | 275 | return type_entry->data.unionation.resolve_status >= status; |
| 276 | case ZigTypeIdEnum: | ||
| 277 | return type_entry->data.enumeration.resolve_status >= status; | ||
| 274 | case ZigTypeIdFnFrame: | 278 | case ZigTypeIdFnFrame: |
| 275 | switch (status) { | 279 | switch (status) { |
| 276 | case ResolveStatusInvalid: | 280 | case ResolveStatusInvalid: |
| ... | @@ -285,32 +289,28 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) { | ... | @@ -285,32 +289,28 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) { |
| 285 | case ResolveStatusLLVMFull: | 289 | case ResolveStatusLLVMFull: |
| 286 | return type_entry->llvm_type != nullptr; | 290 | return type_entry->llvm_type != nullptr; |
| 287 | } | 291 | } |
| 288 | case ZigTypeIdEnum: | 292 | case ZigTypeIdOpaque: |
| 293 | return status < ResolveStatusSizeKnown; | ||
| 294 | case ZigTypeIdPointer: | ||
| 289 | switch (status) { | 295 | switch (status) { |
| 290 | case ResolveStatusUnstarted: | ||
| 291 | return true; | ||
| 292 | case ResolveStatusInvalid: | 296 | case ResolveStatusInvalid: |
| 293 | zig_unreachable(); | 297 | zig_unreachable(); |
| 298 | case ResolveStatusUnstarted: | ||
| 299 | return true; | ||
| 294 | case ResolveStatusZeroBitsKnown: | 300 | case ResolveStatusZeroBitsKnown: |
| 295 | return type_entry->data.enumeration.zero_bits_known; | ||
| 296 | case ResolveStatusAlignmentKnown: | 301 | case ResolveStatusAlignmentKnown: |
| 297 | return type_entry->data.enumeration.zero_bits_known; | ||
| 298 | case ResolveStatusSizeKnown: | 302 | case ResolveStatusSizeKnown: |
| 299 | return type_entry->data.enumeration.complete; | 303 | return type_entry->abi_size != SIZE_MAX; |
| 300 | case ResolveStatusLLVMFwdDecl: | 304 | case ResolveStatusLLVMFwdDecl: |
| 301 | case ResolveStatusLLVMFull: | 305 | case ResolveStatusLLVMFull: |
| 302 | return type_entry->llvm_di_type != nullptr; | 306 | return type_entry->llvm_type != nullptr; |
| 303 | } | 307 | } |
| 304 | zig_unreachable(); | ||
| 305 | case ZigTypeIdOpaque: | ||
| 306 | return status < ResolveStatusSizeKnown; | ||
| 307 | case ZigTypeIdMetaType: | 308 | case ZigTypeIdMetaType: |
| 308 | case ZigTypeIdVoid: | 309 | case ZigTypeIdVoid: |
| 309 | case ZigTypeIdBool: | 310 | case ZigTypeIdBool: |
| 310 | case ZigTypeIdUnreachable: | 311 | case ZigTypeIdUnreachable: |
| 311 | case ZigTypeIdInt: | 312 | case ZigTypeIdInt: |
| 312 | case ZigTypeIdFloat: | 313 | case ZigTypeIdFloat: |
| 313 | case ZigTypeIdPointer: | ||
| 314 | case ZigTypeIdArray: | 314 | case ZigTypeIdArray: |
| 315 | case ZigTypeIdComptimeFloat: | 315 | case ZigTypeIdComptimeFloat: |
| 316 | case ZigTypeIdComptimeInt: | 316 | case ZigTypeIdComptimeInt: |
| ... | @@ -460,8 +460,6 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons | ... | @@ -460,8 +460,6 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons |
| 460 | } | 460 | } |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | assert(type_is_resolved(child_type, ResolveStatusZeroBitsKnown)); | ||
| 464 | |||
| 465 | ZigType *entry = new_type_table_entry(ZigTypeIdPointer); | 463 | ZigType *entry = new_type_table_entry(ZigTypeIdPointer); |
| 466 | 464 | ||
| 467 | const char *star_str = ptr_len_to_star_str(ptr_len); | 465 | const char *star_str = ptr_len_to_star_str(ptr_len); |
| ... | @@ -491,17 +489,21 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons | ... | @@ -491,17 +489,21 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons |
| 491 | buf_ptr(&child_type->name)); | 489 | buf_ptr(&child_type->name)); |
| 492 | } | 490 | } |
| 493 | 491 | ||
| 494 | assert(child_type->id != ZigTypeIdInvalid); | 492 | if (type_is_resolved(child_type, ResolveStatusZeroBitsKnown)) { |
| 495 | 493 | if (type_has_bits(child_type)) { | |
| 496 | if (type_has_bits(child_type)) { | 494 | entry->abi_size = g->builtin_types.entry_usize->abi_size; |
| 497 | entry->abi_size = g->builtin_types.entry_usize->abi_size; | 495 | entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits; |
| 498 | entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits; | 496 | entry->abi_align = g->builtin_types.entry_usize->abi_align; |
| 499 | entry->abi_align = g->builtin_types.entry_usize->abi_align; | 497 | } else { |
| 498 | assert(byte_alignment == 0); | ||
| 499 | entry->abi_size = 0; | ||
| 500 | entry->size_in_bits = 0; | ||
| 501 | entry->abi_align = 0; | ||
| 502 | } | ||
| 500 | } else { | 503 | } else { |
| 501 | assert(byte_alignment == 0); | 504 | entry->abi_size = SIZE_MAX; |
| 502 | entry->abi_size = 0; | 505 | entry->size_in_bits = SIZE_MAX; |
| 503 | entry->size_in_bits = 0; | 506 | entry->abi_align = UINT32_MAX; |
| 504 | entry->abi_align = 0; | ||
| 505 | } | 507 | } |
| 506 | 508 | ||
| 507 | entry->data.pointer.ptr_len = ptr_len; | 509 | entry->data.pointer.ptr_len = ptr_len; |
| ... | @@ -865,7 +867,7 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { | ... | @@ -865,7 +867,7 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 865 | return table_entry->value; | 867 | return table_entry->value; |
| 866 | } | 868 | } |
| 867 | if (fn_type_id->return_type != nullptr) { | 869 | if (fn_type_id->return_type != nullptr) { |
| 868 | if ((err = ensure_complete_type(g, fn_type_id->return_type))) | 870 | if ((err = type_resolve(g, fn_type_id->return_type, ResolveStatusSizeKnown))) |
| 869 | return g->builtin_types.entry_invalid; | 871 | return g->builtin_types.entry_invalid; |
| 870 | assert(fn_type_id->return_type->id != ZigTypeIdOpaque); | 872 | assert(fn_type_id->return_type->id != ZigTypeIdOpaque); |
| 871 | } else { | 873 | } else { |
| ... | @@ -960,31 +962,209 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind | ... | @@ -960,31 +962,209 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind |
| 960 | return entry; | 962 | return entry; |
| 961 | } | 963 | } |
| 962 | 964 | ||
| 963 | ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name) { | 965 | ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, |
| 966 | Buf *type_name, UndefAllowed undef) | ||
| 967 | { | ||
| 964 | size_t backward_branch_count = 0; | 968 | size_t backward_branch_count = 0; |
| 965 | size_t backward_branch_quota = default_backward_branch_quota; | 969 | size_t backward_branch_quota = default_backward_branch_quota; |
| 966 | return ir_eval_const_value(g, scope, node, type_entry, | 970 | return ir_eval_const_value(g, scope, node, type_entry, |
| 967 | &backward_branch_count, &backward_branch_quota, | 971 | &backward_branch_count, &backward_branch_quota, |
| 968 | nullptr, nullptr, node, type_name, nullptr, nullptr); | 972 | nullptr, nullptr, node, type_name, nullptr, nullptr, undef); |
| 969 | } | 973 | } |
| 970 | 974 | ||
| 971 | ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { | 975 | static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, ZigType *parent_type, |
| 972 | ConstExprValue *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type, nullptr); | 976 | ConstExprValue *parent_type_val, bool *is_zero_bits) |
| 973 | if (type_is_invalid(result->type)) | 977 | { |
| 974 | return g->builtin_types.entry_invalid; | 978 | Error err; |
| 979 | if (type_val->special != ConstValSpecialLazy) { | ||
| 980 | assert(type_val->special == ConstValSpecialStatic); | ||
| 981 | if ((type_val->data.x_type->id == ZigTypeIdStruct && | ||
| 982 | type_val->data.x_type->data.structure.resolve_loop_flag_zero_bits) || | ||
| 983 | (type_val->data.x_type->id == ZigTypeIdUnion && | ||
| 984 | type_val->data.x_type->data.unionation.resolve_loop_flag_zero_bits) || | ||
| 985 | type_val->data.x_type->id == ZigTypeIdPointer) | ||
| 986 | { | ||
| 987 | // Does a struct/union which contains a pointer field to itself have bits? Yes. | ||
| 988 | *is_zero_bits = false; | ||
| 989 | return ErrorNone; | ||
| 990 | } | ||
| 991 | if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusZeroBitsKnown))) | ||
| 992 | return err; | ||
| 993 | *is_zero_bits = (type_val->data.x_type->abi_size == 0); | ||
| 994 | return ErrorNone; | ||
| 995 | } | ||
| 996 | switch (type_val->data.x_lazy->id) { | ||
| 997 | case LazyValueIdInvalid: | ||
| 998 | case LazyValueIdAlignOf: | ||
| 999 | zig_unreachable(); | ||
| 1000 | case LazyValueIdPtrType: { | ||
| 1001 | LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy); | ||
| 975 | 1002 | ||
| 976 | assert(result->special != ConstValSpecialRuntime); | 1003 | if (parent_type_val == &lazy_ptr_type->elem_type->value) { |
| 977 | // Reject undefined as valid `type` type even though the specification | 1004 | // Does a struct which contains a pointer field to itself have bits? Yes. |
| 978 | // allows it to be casted to anything. | 1005 | *is_zero_bits = false; |
| 979 | // See also ir_resolve_type() | 1006 | return ErrorNone; |
| 980 | if (result->special == ConstValSpecialUndef) { | 1007 | } else { |
| 981 | add_node_error(g, node, | 1008 | if (parent_type_val == nullptr) { |
| 982 | buf_sprintf("expected type 'type', found '%s'", | 1009 | parent_type_val = type_val; |
| 983 | buf_ptr(&g->builtin_types.entry_undef->name))); | 1010 | } |
| 984 | return g->builtin_types.entry_invalid; | 1011 | return type_val_resolve_zero_bits(g, &lazy_ptr_type->elem_type->value, parent_type, |
| 1012 | parent_type_val, is_zero_bits); | ||
| 1013 | } | ||
| 1014 | } | ||
| 1015 | case LazyValueIdOptType: | ||
| 1016 | case LazyValueIdSliceType: | ||
| 1017 | *is_zero_bits = false; | ||
| 1018 | return ErrorNone; | ||
| 1019 | case LazyValueIdFnType: { | ||
| 1020 | LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy); | ||
| 1021 | *is_zero_bits = lazy_fn_type->is_generic; | ||
| 1022 | return ErrorNone; | ||
| 1023 | } | ||
| 1024 | } | ||
| 1025 | zig_unreachable(); | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool *is_opaque_type) { | ||
| 1029 | if (type_val->special != ConstValSpecialLazy) { | ||
| 1030 | assert(type_val->special == ConstValSpecialStatic); | ||
| 1031 | *is_opaque_type = (type_val->data.x_type->id == ZigTypeIdOpaque); | ||
| 1032 | return ErrorNone; | ||
| 1033 | } | ||
| 1034 | switch (type_val->data.x_lazy->id) { | ||
| 1035 | case LazyValueIdInvalid: | ||
| 1036 | case LazyValueIdAlignOf: | ||
| 1037 | zig_unreachable(); | ||
| 1038 | case LazyValueIdSliceType: | ||
| 1039 | case LazyValueIdPtrType: | ||
| 1040 | case LazyValueIdFnType: | ||
| 1041 | case LazyValueIdOptType: | ||
| 1042 | *is_opaque_type = false; | ||
| 1043 | return ErrorNone; | ||
| 985 | } | 1044 | } |
| 1045 | zig_unreachable(); | ||
| 1046 | } | ||
| 986 | 1047 | ||
| 987 | assert(result->data.x_type != nullptr); | 1048 | static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue *type_val) { |
| 1049 | if (type_val->special != ConstValSpecialLazy) { | ||
| 1050 | return type_requires_comptime(g, type_val->data.x_type); | ||
| 1051 | } | ||
| 1052 | switch (type_val->data.x_lazy->id) { | ||
| 1053 | case LazyValueIdInvalid: | ||
| 1054 | case LazyValueIdAlignOf: | ||
| 1055 | zig_unreachable(); | ||
| 1056 | case LazyValueIdSliceType: { | ||
| 1057 | LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy); | ||
| 1058 | if (type_is_invalid(lazy_slice_type->elem_type)) | ||
| 1059 | return ReqCompTimeInvalid; | ||
| 1060 | return type_requires_comptime(g, lazy_slice_type->elem_type); | ||
| 1061 | } | ||
| 1062 | case LazyValueIdPtrType: { | ||
| 1063 | LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy); | ||
| 1064 | return type_val_resolve_requires_comptime(g, &lazy_ptr_type->elem_type->value); | ||
| 1065 | } | ||
| 1066 | case LazyValueIdOptType: { | ||
| 1067 | LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy); | ||
| 1068 | return type_val_resolve_requires_comptime(g, &lazy_opt_type->payload_type->value); | ||
| 1069 | } | ||
| 1070 | case LazyValueIdFnType: { | ||
| 1071 | LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy); | ||
| 1072 | if (lazy_fn_type->is_generic) | ||
| 1073 | return ReqCompTimeYes; | ||
| 1074 | switch (type_val_resolve_requires_comptime(g, &lazy_fn_type->return_type->value)) { | ||
| 1075 | case ReqCompTimeInvalid: | ||
| 1076 | return ReqCompTimeInvalid; | ||
| 1077 | case ReqCompTimeYes: | ||
| 1078 | return ReqCompTimeYes; | ||
| 1079 | case ReqCompTimeNo: | ||
| 1080 | break; | ||
| 1081 | } | ||
| 1082 | size_t param_count = lazy_fn_type->proto_node->data.fn_proto.params.length; | ||
| 1083 | for (size_t i = 0; i < param_count; i += 1) { | ||
| 1084 | AstNode *param_node = lazy_fn_type->proto_node->data.fn_proto.params.at(i); | ||
| 1085 | bool param_is_var_args = param_node->data.param_decl.is_var_args; | ||
| 1086 | if (param_is_var_args) break; | ||
| 1087 | switch (type_val_resolve_requires_comptime(g, &lazy_fn_type->param_types[i]->value)) { | ||
| 1088 | case ReqCompTimeInvalid: | ||
| 1089 | return ReqCompTimeInvalid; | ||
| 1090 | case ReqCompTimeYes: | ||
| 1091 | return ReqCompTimeYes; | ||
| 1092 | case ReqCompTimeNo: | ||
| 1093 | break; | ||
| 1094 | } | ||
| 1095 | } | ||
| 1096 | return ReqCompTimeNo; | ||
| 1097 | } | ||
| 1098 | } | ||
| 1099 | zig_unreachable(); | ||
| 1100 | } | ||
| 1101 | |||
| 1102 | Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align) { | ||
| 1103 | Error err; | ||
| 1104 | if (type_val->special != ConstValSpecialLazy) { | ||
| 1105 | assert(type_val->special == ConstValSpecialStatic); | ||
| 1106 | ZigType *ty = type_val->data.x_type; | ||
| 1107 | if (ty->id == ZigTypeIdPointer) { | ||
| 1108 | *abi_align = g->builtin_types.entry_usize->abi_align; | ||
| 1109 | return ErrorNone; | ||
| 1110 | } | ||
| 1111 | if ((err = type_resolve(g, ty, ResolveStatusAlignmentKnown))) | ||
| 1112 | return err; | ||
| 1113 | *abi_align = ty->abi_align; | ||
| 1114 | return ErrorNone; | ||
| 1115 | } | ||
| 1116 | switch (type_val->data.x_lazy->id) { | ||
| 1117 | case LazyValueIdInvalid: | ||
| 1118 | case LazyValueIdAlignOf: | ||
| 1119 | zig_unreachable(); | ||
| 1120 | case LazyValueIdSliceType: | ||
| 1121 | case LazyValueIdPtrType: | ||
| 1122 | case LazyValueIdFnType: | ||
| 1123 | *abi_align = g->builtin_types.entry_usize->abi_align; | ||
| 1124 | return ErrorNone; | ||
| 1125 | case LazyValueIdOptType: { | ||
| 1126 | LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy); | ||
| 1127 | return type_val_resolve_abi_align(g, &lazy_opt_type->payload_type->value, abi_align); | ||
| 1128 | } | ||
| 1129 | } | ||
| 1130 | zig_unreachable(); | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ConstExprValue *type_val) { | ||
| 1134 | if (type_val->special != ConstValSpecialLazy) { | ||
| 1135 | return type_has_one_possible_value(g, type_val->data.x_type); | ||
| 1136 | } | ||
| 1137 | switch (type_val->data.x_lazy->id) { | ||
| 1138 | case LazyValueIdInvalid: | ||
| 1139 | case LazyValueIdAlignOf: | ||
| 1140 | zig_unreachable(); | ||
| 1141 | case LazyValueIdSliceType: // it has the len field | ||
| 1142 | case LazyValueIdOptType: // it has the optional bit | ||
| 1143 | case LazyValueIdFnType: | ||
| 1144 | return OnePossibleValueNo; | ||
| 1145 | case LazyValueIdPtrType: { | ||
| 1146 | Error err; | ||
| 1147 | bool zero_bits; | ||
| 1148 | if ((err = type_val_resolve_zero_bits(g, type_val, nullptr, nullptr, &zero_bits))) { | ||
| 1149 | return OnePossibleValueInvalid; | ||
| 1150 | } | ||
| 1151 | if (zero_bits) { | ||
| 1152 | return OnePossibleValueYes; | ||
| 1153 | } else { | ||
| 1154 | return OnePossibleValueNo; | ||
| 1155 | } | ||
| 1156 | } | ||
| 1157 | } | ||
| 1158 | zig_unreachable(); | ||
| 1159 | } | ||
| 1160 | |||
| 1161 | ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { | ||
| 1162 | ConstExprValue *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type, | ||
| 1163 | nullptr, UndefBad); | ||
| 1164 | if (type_is_invalid(result->type)) | ||
| 1165 | return g->builtin_types.entry_invalid; | ||
| 1166 | src_assert(result->special == ConstValSpecialStatic, node); | ||
| 1167 | src_assert(result->data.x_type != nullptr, node); | ||
| 988 | return result->data.x_type; | 1168 | return result->data.x_type; |
| 989 | } | 1169 | } |
| 990 | 1170 | ||
| ... | @@ -1032,7 +1212,8 @@ void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_cou | ... | @@ -1032,7 +1212,8 @@ void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_cou |
| 1032 | } | 1212 | } |
| 1033 | 1213 | ||
| 1034 | static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_t *result) { | 1214 | static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_t *result) { |
| 1035 | ConstExprValue *align_result = analyze_const_value(g, scope, node, get_align_amt_type(g), nullptr); | 1215 | ConstExprValue *align_result = analyze_const_value(g, scope, node, get_align_amt_type(g), |
| 1216 | nullptr, UndefBad); | ||
| 1036 | if (type_is_invalid(align_result->type)) | 1217 | if (type_is_invalid(align_result->type)) |
| 1037 | return false; | 1218 | return false; |
| 1038 | 1219 | ||
| ... | @@ -1054,7 +1235,7 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf ** | ... | @@ -1054,7 +1235,7 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf ** |
| 1054 | ZigType *ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, | 1235 | ZigType *ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, |
| 1055 | PtrLenUnknown, 0, 0, 0, false); | 1236 | PtrLenUnknown, 0, 0, 0, false); |
| 1056 | ZigType *str_type = get_slice_type(g, ptr_type); | 1237 | ZigType *str_type = get_slice_type(g, ptr_type); |
| 1057 | ConstExprValue *result_val = analyze_const_value(g, scope, node, str_type, nullptr); | 1238 | ConstExprValue *result_val = analyze_const_value(g, scope, node, str_type, nullptr, UndefBad); |
| 1058 | if (type_is_invalid(result_val->type)) | 1239 | if (type_is_invalid(result_val->type)) |
| 1059 | return false; | 1240 | return false; |
| 1060 | 1241 | ||
| ... | @@ -1404,7 +1585,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc | ... | @@ -1404,7 +1585,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc |
| 1404 | add_node_error(g, proto_node, | 1585 | add_node_error(g, proto_node, |
| 1405 | buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); | 1586 | buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); |
| 1406 | return g->builtin_types.entry_invalid; | 1587 | return g->builtin_types.entry_invalid; |
| 1407 | //return get_generic_fn_type(g, &fn_type_id); | ||
| 1408 | } | 1588 | } |
| 1409 | 1589 | ||
| 1410 | ZigType *specified_return_type = analyze_type_expr(g, child_scope, fn_proto->return_type); | 1590 | ZigType *specified_return_type = analyze_type_expr(g, child_scope, fn_proto->return_type); |
| ... | @@ -1423,14 +1603,17 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc | ... | @@ -1423,14 +1603,17 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc |
| 1423 | } | 1603 | } |
| 1424 | 1604 | ||
| 1425 | if (!calling_convention_allows_zig_types(fn_type_id.cc) && | 1605 | if (!calling_convention_allows_zig_types(fn_type_id.cc) && |
| 1426 | fn_type_id.return_type->id != ZigTypeIdVoid && | 1606 | fn_type_id.return_type->id != ZigTypeIdVoid) |
| 1427 | !type_allowed_in_extern(g, fn_type_id.return_type)) | ||
| 1428 | { | 1607 | { |
| 1429 | add_node_error(g, fn_proto->return_type, | 1608 | if ((err = type_resolve(g, fn_type_id.return_type, ResolveStatusSizeKnown))) |
| 1430 | buf_sprintf("return type '%s' not allowed in function with calling convention '%s'", | 1609 | return g->builtin_types.entry_invalid; |
| 1431 | buf_ptr(&fn_type_id.return_type->name), | 1610 | if (!type_allowed_in_extern(g, fn_type_id.return_type)) { |
| 1432 | calling_convention_name(fn_type_id.cc))); | 1611 | add_node_error(g, fn_proto->return_type, |
| 1433 | return g->builtin_types.entry_invalid; | 1612 | buf_sprintf("return type '%s' not allowed in function with calling convention '%s'", |
| 1613 | buf_ptr(&fn_type_id.return_type->name), | ||
| 1614 | calling_convention_name(fn_type_id.cc))); | ||
| 1615 | return g->builtin_types.entry_invalid; | ||
| 1616 | } | ||
| 1434 | } | 1617 | } |
| 1435 | 1618 | ||
| 1436 | switch (fn_type_id.return_type->id) { | 1619 | switch (fn_type_id.return_type->id) { |
| ... | @@ -1490,7 +1673,7 @@ bool type_is_invalid(ZigType *type_entry) { | ... | @@ -1490,7 +1673,7 @@ bool type_is_invalid(ZigType *type_entry) { |
| 1490 | case ZigTypeIdUnion: | 1673 | case ZigTypeIdUnion: |
| 1491 | return type_entry->data.unionation.resolve_status == ResolveStatusInvalid; | 1674 | return type_entry->data.unionation.resolve_status == ResolveStatusInvalid; |
| 1492 | case ZigTypeIdEnum: | 1675 | case ZigTypeIdEnum: |
| 1493 | return type_entry->data.enumeration.is_invalid; | 1676 | return type_entry->data.enumeration.resolve_status == ResolveStatusInvalid; |
| 1494 | default: | 1677 | default: |
| 1495 | return false; | 1678 | return false; |
| 1496 | } | 1679 | } |
| ... | @@ -1599,12 +1782,11 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { | ... | @@ -1599,12 +1782,11 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1599 | 1782 | ||
| 1600 | AstNode *decl_node = struct_type->data.structure.decl_node; | 1783 | AstNode *decl_node = struct_type->data.structure.decl_node; |
| 1601 | 1784 | ||
| 1602 | if (struct_type->data.structure.resolve_loop_flag) { | 1785 | if (struct_type->data.structure.resolve_loop_flag_other) { |
| 1603 | if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { | 1786 | if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { |
| 1604 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 1787 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1605 | ErrorMsg *msg = add_node_error(g, decl_node, | 1788 | add_node_error(g, decl_node, |
| 1606 | buf_sprintf("struct '%s' contains itself", buf_ptr(&struct_type->name))); | 1789 | buf_sprintf("struct '%s' depends on itself", buf_ptr(&struct_type->name))); |
| 1607 | emit_error_notes_for_ref_stack(g, msg); | ||
| 1608 | } | 1790 | } |
| 1609 | return ErrorSemanticAnalyzeFail; | 1791 | return ErrorSemanticAnalyzeFail; |
| 1610 | } | 1792 | } |
| ... | @@ -1615,18 +1797,42 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { | ... | @@ -1615,18 +1797,42 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1615 | size_t field_count = struct_type->data.structure.src_field_count; | 1797 | size_t field_count = struct_type->data.structure.src_field_count; |
| 1616 | 1798 | ||
| 1617 | bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked); | 1799 | bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked); |
| 1618 | struct_type->data.structure.resolve_loop_flag = true; | 1800 | struct_type->data.structure.resolve_loop_flag_other = true; |
| 1619 | 1801 | ||
| 1620 | uint32_t *host_int_bytes = packed ? allocate<uint32_t>(struct_type->data.structure.gen_field_count) : nullptr; | 1802 | uint32_t *host_int_bytes = packed ? allocate<uint32_t>(struct_type->data.structure.gen_field_count) : nullptr; |
| 1621 | 1803 | ||
| 1622 | // Resolve sizes of all the field types. Done before the offset loop because the offset | 1804 | // Resolve types for fields and then resolve sizes of all the field types. |
| 1623 | // loop has to look ahead. | 1805 | // This is done before the offset loop because the offset loop has to look ahead. |
| 1624 | for (size_t i = 0; i < field_count; i += 1) { | 1806 | for (size_t i = 0; i < field_count; i += 1) { |
| 1807 | AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); | ||
| 1625 | TypeStructField *field = &struct_type->data.structure.fields[i]; | 1808 | TypeStructField *field = &struct_type->data.structure.fields[i]; |
| 1809 | |||
| 1810 | if ((err = ir_resolve_lazy(g, field_source_node, field->type_val))) { | ||
| 1811 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 1812 | return err; | ||
| 1813 | } | ||
| 1814 | field->type_entry = field->type_val->data.x_type; | ||
| 1815 | |||
| 1626 | if ((err = type_resolve(g, field->type_entry, ResolveStatusSizeKnown))) { | 1816 | if ((err = type_resolve(g, field->type_entry, ResolveStatusSizeKnown))) { |
| 1627 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 1817 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 1818 | return err; | ||
| 1819 | } | ||
| 1820 | |||
| 1821 | if (struct_type->data.structure.layout == ContainerLayoutExtern && | ||
| 1822 | !type_allowed_in_extern(g, field->type_entry)) | ||
| 1823 | { | ||
| 1824 | add_node_error(g, field_source_node, | ||
| 1825 | buf_sprintf("extern structs cannot contain fields of type '%s'", | ||
| 1826 | buf_ptr(&field->type_entry->name))); | ||
| 1827 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 1628 | return ErrorSemanticAnalyzeFail; | 1828 | return ErrorSemanticAnalyzeFail; |
| 1829 | } else if (packed) { | ||
| 1830 | if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field->type_entry, field_source_node))) { | ||
| 1831 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 1832 | return err; | ||
| 1833 | } | ||
| 1629 | } | 1834 | } |
| 1835 | |||
| 1630 | } | 1836 | } |
| 1631 | 1837 | ||
| 1632 | size_t packed_bits_offset = 0; | 1838 | size_t packed_bits_offset = 0; |
| ... | @@ -1690,9 +1896,9 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { | ... | @@ -1690,9 +1896,9 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1690 | break; | 1896 | break; |
| 1691 | } | 1897 | } |
| 1692 | } | 1898 | } |
| 1693 | size_t next_abi_align = (next_src_field_index == field_count) ? | 1899 | size_t next_align = (next_src_field_index == field_count) ? |
| 1694 | abi_align : struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align; | 1900 | abi_align : struct_type->data.structure.fields[next_src_field_index].align; |
| 1695 | next_offset = next_field_offset(next_offset, abi_align, field_type->abi_size, next_abi_align); | 1901 | next_offset = next_field_offset(next_offset, abi_align, field_type->abi_size, next_align); |
| 1696 | size_in_bits = next_offset * 8; | 1902 | size_in_bits = next_offset * 8; |
| 1697 | } | 1903 | } |
| 1698 | } | 1904 | } |
| ... | @@ -1708,7 +1914,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { | ... | @@ -1708,7 +1914,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 1708 | struct_type->size_in_bits = size_in_bits; | 1914 | struct_type->size_in_bits = size_in_bits; |
| 1709 | struct_type->data.structure.resolve_status = ResolveStatusSizeKnown; | 1915 | struct_type->data.structure.resolve_status = ResolveStatusSizeKnown; |
| 1710 | struct_type->data.structure.gen_field_count = (uint32_t)gen_field_index; | 1916 | struct_type->data.structure.gen_field_count = (uint32_t)gen_field_index; |
| 1711 | struct_type->data.structure.resolve_loop_flag = false; | 1917 | struct_type->data.structure.resolve_loop_flag_other = false; |
| 1712 | struct_type->data.structure.host_int_bytes = host_int_bytes; | 1918 | struct_type->data.structure.host_int_bytes = host_int_bytes; |
| 1713 | 1919 | ||
| 1714 | return ErrorNone; | 1920 | return ErrorNone; |
| ... | @@ -1728,22 +1934,21 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { | ... | @@ -1728,22 +1934,21 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { |
| 1728 | if (union_type->data.unionation.resolve_status >= ResolveStatusAlignmentKnown) | 1934 | if (union_type->data.unionation.resolve_status >= ResolveStatusAlignmentKnown) |
| 1729 | return ErrorNone; | 1935 | return ErrorNone; |
| 1730 | 1936 | ||
| 1731 | if (union_type->data.unionation.resolve_loop_flag) { | 1937 | AstNode *decl_node = union_type->data.structure.decl_node; |
| 1732 | if (!union_type->data.unionation.reported_infinite_err) { | 1938 | |
| 1733 | AstNode *decl_node = union_type->data.unionation.decl_node; | 1939 | if (union_type->data.unionation.resolve_loop_flag_other) { |
| 1734 | union_type->data.unionation.reported_infinite_err = true; | 1940 | if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) { |
| 1735 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 1941 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 1736 | ErrorMsg *msg = add_node_error(g, decl_node, | 1942 | add_node_error(g, decl_node, |
| 1737 | buf_sprintf("union '%s' contains itself", buf_ptr(&union_type->name))); | 1943 | buf_sprintf("union '%s' depends on itself", buf_ptr(&union_type->name))); |
| 1738 | emit_error_notes_for_ref_stack(g, msg); | ||
| 1739 | } | 1944 | } |
| 1740 | return ErrorSemanticAnalyzeFail; | 1945 | return ErrorSemanticAnalyzeFail; |
| 1741 | } | 1946 | } |
| 1742 | 1947 | ||
| 1743 | // set temporary flag | 1948 | // set temporary flag |
| 1744 | union_type->data.unionation.resolve_loop_flag = true; | 1949 | union_type->data.unionation.resolve_loop_flag_other = true; |
| 1745 | 1950 | ||
| 1746 | ZigType *most_aligned_union_member = nullptr; | 1951 | TypeUnionField *most_aligned_union_member = nullptr; |
| 1747 | uint32_t field_count = union_type->data.unionation.src_field_count; | 1952 | uint32_t field_count = union_type->data.unionation.src_field_count; |
| 1748 | bool packed = union_type->data.unionation.layout == ContainerLayoutPacked; | 1953 | bool packed = union_type->data.unionation.layout == ContainerLayoutPacked; |
| 1749 | 1954 | ||
| ... | @@ -1752,34 +1957,40 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { | ... | @@ -1752,34 +1957,40 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { |
| 1752 | if (field->gen_index == UINT32_MAX) | 1957 | if (field->gen_index == UINT32_MAX) |
| 1753 | continue; | 1958 | continue; |
| 1754 | 1959 | ||
| 1755 | size_t this_field_align; | 1960 | AstNode *align_expr = field->decl_node->data.struct_field.align_expr; |
| 1756 | if (packed) { | 1961 | if (align_expr != nullptr) { |
| 1757 | // TODO: https://github.com/ziglang/zig/issues/1512 | 1962 | if (!analyze_const_align(g, &union_type->data.unionation.decls_scope->base, align_expr, |
| 1758 | this_field_align = 1; | 1963 | &field->align)) |
| 1759 | // This is the same hack as resolve_struct_alignment. See the comment there. | 1964 | { |
| 1760 | } else if (field->type_entry == nullptr) { | 1965 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 1761 | this_field_align = g->builtin_types.entry_usize->abi_align; | 1966 | return err; |
| 1762 | } else { | 1967 | } |
| 1968 | add_node_error(g, field->decl_node, | ||
| 1969 | buf_create_from_str("TODO implement field alignment syntax for unions. https://github.com/ziglang/zig/issues/3125")); | ||
| 1970 | } else if (packed) { | ||
| 1971 | field->align = 1; | ||
| 1972 | } else if (field->type_entry != nullptr) { | ||
| 1763 | if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) { | 1973 | if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) { |
| 1764 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 1974 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 1765 | return ErrorSemanticAnalyzeFail; | 1975 | return err; |
| 1976 | } | ||
| 1977 | field->align = field->type_entry->abi_align; | ||
| 1978 | } else { | ||
| 1979 | if ((err = type_val_resolve_abi_align(g, field->type_val, &field->align))) { | ||
| 1980 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | ||
| 1981 | return err; | ||
| 1766 | } | 1982 | } |
| 1767 | |||
| 1768 | if (union_type->data.unionation.resolve_status == ResolveStatusInvalid) | 1983 | if (union_type->data.unionation.resolve_status == ResolveStatusInvalid) |
| 1769 | return ErrorSemanticAnalyzeFail; | 1984 | return ErrorSemanticAnalyzeFail; |
| 1770 | |||
| 1771 | this_field_align = field->type_entry->abi_align; | ||
| 1772 | } | 1985 | } |
| 1773 | 1986 | ||
| 1774 | if (most_aligned_union_member == nullptr || | 1987 | if (most_aligned_union_member == nullptr || field->align > most_aligned_union_member->align) { |
| 1775 | this_field_align > most_aligned_union_member->abi_align) | 1988 | most_aligned_union_member = field; |
| 1776 | { | ||
| 1777 | most_aligned_union_member = field->type_entry; | ||
| 1778 | } | 1989 | } |
| 1779 | } | 1990 | } |
| 1780 | 1991 | ||
| 1781 | // unset temporary flag | 1992 | // unset temporary flag |
| 1782 | union_type->data.unionation.resolve_loop_flag = false; | 1993 | union_type->data.unionation.resolve_loop_flag_other = false; |
| 1783 | union_type->data.unionation.resolve_status = ResolveStatusAlignmentKnown; | 1994 | union_type->data.unionation.resolve_status = ResolveStatusAlignmentKnown; |
| 1784 | union_type->data.unionation.most_aligned_union_member = most_aligned_union_member; | 1995 | union_type->data.unionation.most_aligned_union_member = most_aligned_union_member; |
| 1785 | 1996 | ||
| ... | @@ -1793,18 +2004,18 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { | ... | @@ -1793,18 +2004,18 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { |
| 1793 | union_type->abi_align = tag_type->abi_align; | 2004 | union_type->abi_align = tag_type->abi_align; |
| 1794 | union_type->data.unionation.gen_tag_index = SIZE_MAX; | 2005 | union_type->data.unionation.gen_tag_index = SIZE_MAX; |
| 1795 | union_type->data.unionation.gen_union_index = SIZE_MAX; | 2006 | union_type->data.unionation.gen_union_index = SIZE_MAX; |
| 1796 | } else if (tag_type->abi_align > most_aligned_union_member->abi_align) { | 2007 | } else if (tag_type->abi_align > most_aligned_union_member->align) { |
| 1797 | union_type->abi_align = tag_type->abi_align; | 2008 | union_type->abi_align = tag_type->abi_align; |
| 1798 | union_type->data.unionation.gen_tag_index = 0; | 2009 | union_type->data.unionation.gen_tag_index = 0; |
| 1799 | union_type->data.unionation.gen_union_index = 1; | 2010 | union_type->data.unionation.gen_union_index = 1; |
| 1800 | } else { | 2011 | } else { |
| 1801 | union_type->abi_align = most_aligned_union_member->abi_align; | 2012 | union_type->abi_align = most_aligned_union_member->align; |
| 1802 | union_type->data.unionation.gen_union_index = 0; | 2013 | union_type->data.unionation.gen_union_index = 0; |
| 1803 | union_type->data.unionation.gen_tag_index = 1; | 2014 | union_type->data.unionation.gen_tag_index = 1; |
| 1804 | } | 2015 | } |
| 1805 | } else { | 2016 | } else { |
| 1806 | assert(most_aligned_union_member != nullptr); | 2017 | assert(most_aligned_union_member != nullptr); |
| 1807 | union_type->abi_align = most_aligned_union_member->abi_align; | 2018 | union_type->abi_align = most_aligned_union_member->align; |
| 1808 | union_type->data.unionation.gen_union_index = SIZE_MAX; | 2019 | union_type->data.unionation.gen_union_index = SIZE_MAX; |
| 1809 | union_type->data.unionation.gen_tag_index = SIZE_MAX; | 2020 | union_type->data.unionation.gen_tag_index = SIZE_MAX; |
| 1810 | } | 2021 | } |
| ... | @@ -1812,6 +2023,17 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { | ... | @@ -1812,6 +2023,17 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { |
| 1812 | return ErrorNone; | 2023 | return ErrorNone; |
| 1813 | } | 2024 | } |
| 1814 | 2025 | ||
| 2026 | ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field) { | ||
| 2027 | Error err; | ||
| 2028 | if (union_field->type_entry == nullptr) { | ||
| 2029 | if ((err = ir_resolve_lazy(g, union_field->decl_node, union_field->type_val))) { | ||
| 2030 | return nullptr; | ||
| 2031 | } | ||
| 2032 | union_field->type_entry = union_field->type_val->data.x_type; | ||
| 2033 | } | ||
| 2034 | return union_field->type_entry; | ||
| 2035 | } | ||
| 2036 | |||
| 1815 | static Error resolve_union_type(CodeGen *g, ZigType *union_type) { | 2037 | static Error resolve_union_type(CodeGen *g, ZigType *union_type) { |
| 1816 | assert(union_type->id == ZigTypeIdUnion); | 2038 | assert(union_type->id == ZigTypeIdUnion); |
| 1817 | 2039 | ||
| ... | @@ -1831,30 +2053,32 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { | ... | @@ -1831,30 +2053,32 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { |
| 1831 | assert(decl_node->type == NodeTypeContainerDecl); | 2053 | assert(decl_node->type == NodeTypeContainerDecl); |
| 1832 | 2054 | ||
| 1833 | uint32_t field_count = union_type->data.unionation.src_field_count; | 2055 | uint32_t field_count = union_type->data.unionation.src_field_count; |
| 1834 | ZigType *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member; | 2056 | TypeUnionField *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member; |
| 1835 | 2057 | ||
| 1836 | assert(union_type->data.unionation.fields); | 2058 | assert(union_type->data.unionation.fields); |
| 1837 | 2059 | ||
| 1838 | size_t union_abi_size = 0; | 2060 | size_t union_abi_size = 0; |
| 1839 | size_t union_size_in_bits = 0; | 2061 | size_t union_size_in_bits = 0; |
| 1840 | 2062 | ||
| 1841 | if (union_type->data.unionation.resolve_loop_flag) { | 2063 | if (union_type->data.unionation.resolve_loop_flag_other) { |
| 1842 | if (!union_type->data.unionation.reported_infinite_err) { | 2064 | if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) { |
| 1843 | union_type->data.unionation.reported_infinite_err = true; | ||
| 1844 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2065 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 1845 | ErrorMsg *msg = add_node_error(g, decl_node, | 2066 | add_node_error(g, decl_node, |
| 1846 | buf_sprintf("union '%s' depends on its own size", buf_ptr(&union_type->name))); | 2067 | buf_sprintf("union '%s' depends on itself", buf_ptr(&union_type->name))); |
| 1847 | emit_error_notes_for_ref_stack(g, msg); | ||
| 1848 | } | 2068 | } |
| 1849 | return ErrorSemanticAnalyzeFail; | 2069 | return ErrorSemanticAnalyzeFail; |
| 1850 | } | 2070 | } |
| 1851 | 2071 | ||
| 1852 | // set temporary flag | 2072 | // set temporary flag |
| 1853 | union_type->data.unionation.resolve_loop_flag = true; | 2073 | union_type->data.unionation.resolve_loop_flag_other = true; |
| 1854 | 2074 | ||
| 1855 | for (uint32_t i = 0; i < field_count; i += 1) { | 2075 | for (uint32_t i = 0; i < field_count; i += 1) { |
| 1856 | TypeUnionField *union_field = &union_type->data.unionation.fields[i]; | 2076 | TypeUnionField *union_field = &union_type->data.unionation.fields[i]; |
| 1857 | ZigType *field_type = union_field->type_entry; | 2077 | ZigType *field_type = resolve_union_field_type(g, union_field); |
| 2078 | if (field_type == nullptr) { | ||
| 2079 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | ||
| 2080 | return ErrorSemanticAnalyzeFail; | ||
| 2081 | } | ||
| 1858 | 2082 | ||
| 1859 | if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) { | 2083 | if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) { |
| 1860 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2084 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| ... | @@ -1874,11 +2098,11 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { | ... | @@ -1874,11 +2098,11 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { |
| 1874 | // The union itself for now has to be treated as being independently aligned. | 2098 | // The union itself for now has to be treated as being independently aligned. |
| 1875 | // See https://github.com/ziglang/zig/issues/2166. | 2099 | // See https://github.com/ziglang/zig/issues/2166. |
| 1876 | if (most_aligned_union_member != nullptr) { | 2100 | if (most_aligned_union_member != nullptr) { |
| 1877 | union_abi_size = align_forward(union_abi_size, most_aligned_union_member->abi_align); | 2101 | union_abi_size = align_forward(union_abi_size, most_aligned_union_member->align); |
| 1878 | } | 2102 | } |
| 1879 | 2103 | ||
| 1880 | // unset temporary flag | 2104 | // unset temporary flag |
| 1881 | union_type->data.unionation.resolve_loop_flag = false; | 2105 | union_type->data.unionation.resolve_loop_flag_other = false; |
| 1882 | union_type->data.unionation.resolve_status = ResolveStatusSizeKnown; | 2106 | union_type->data.unionation.resolve_status = ResolveStatusSizeKnown; |
| 1883 | union_type->data.unionation.union_abi_size = union_abi_size; | 2107 | union_type->data.unionation.union_abi_size = union_abi_size; |
| 1884 | 2108 | ||
| ... | @@ -1897,7 +2121,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { | ... | @@ -1897,7 +2121,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { |
| 1897 | field_sizes[union_type->data.unionation.gen_tag_index] = tag_type->abi_size; | 2121 | field_sizes[union_type->data.unionation.gen_tag_index] = tag_type->abi_size; |
| 1898 | field_aligns[union_type->data.unionation.gen_tag_index] = tag_type->abi_align; | 2122 | field_aligns[union_type->data.unionation.gen_tag_index] = tag_type->abi_align; |
| 1899 | field_sizes[union_type->data.unionation.gen_union_index] = union_abi_size; | 2123 | field_sizes[union_type->data.unionation.gen_union_index] = union_abi_size; |
| 1900 | field_aligns[union_type->data.unionation.gen_union_index] = most_aligned_union_member->abi_align; | 2124 | field_aligns[union_type->data.unionation.gen_union_index] = most_aligned_union_member->align; |
| 1901 | size_t field2_offset = next_field_offset(0, union_type->abi_align, field_sizes[0], field_aligns[1]); | 2125 | size_t field2_offset = next_field_offset(0, union_type->abi_align, field_sizes[0], field_aligns[1]); |
| 1902 | union_type->abi_size = next_field_offset(field2_offset, union_type->abi_align, field_sizes[1], union_type->abi_align); | 2126 | union_type->abi_size = next_field_offset(field2_offset, union_type->abi_align, field_sizes[1], union_type->abi_align); |
| 1903 | union_type->size_in_bits = union_type->abi_size * 8; | 2127 | union_type->size_in_bits = union_type->abi_size * 8; |
| ... | @@ -1925,24 +2149,25 @@ static bool type_is_valid_extern_enum_tag(CodeGen *g, ZigType *ty) { | ... | @@ -1925,24 +2149,25 @@ static bool type_is_valid_extern_enum_tag(CodeGen *g, ZigType *ty) { |
| 1925 | static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | 2149 | static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 1926 | assert(enum_type->id == ZigTypeIdEnum); | 2150 | assert(enum_type->id == ZigTypeIdEnum); |
| 1927 | 2151 | ||
| 1928 | if (enum_type->data.enumeration.is_invalid) | 2152 | if (enum_type->data.enumeration.resolve_status == ResolveStatusInvalid) |
| 1929 | return ErrorSemanticAnalyzeFail; | 2153 | return ErrorSemanticAnalyzeFail; |
| 1930 | 2154 | if (enum_type->data.enumeration.resolve_status >= ResolveStatusZeroBitsKnown) | |
| 1931 | if (enum_type->data.enumeration.zero_bits_known) | ||
| 1932 | return ErrorNone; | 2155 | return ErrorNone; |
| 1933 | 2156 | ||
| 1934 | if (enum_type->data.enumeration.zero_bits_loop_flag) { | 2157 | AstNode *decl_node = enum_type->data.enumeration.decl_node; |
| 1935 | ErrorMsg *msg = add_node_error(g, enum_type->data.enumeration.decl_node, | 2158 | assert(decl_node->type == NodeTypeContainerDecl); |
| 1936 | buf_sprintf("'%s' depends on itself", buf_ptr(&enum_type->name))); | 2159 | |
| 1937 | emit_error_notes_for_ref_stack(g, msg); | 2160 | if (enum_type->data.enumeration.resolve_loop_flag) { |
| 1938 | enum_type->data.enumeration.is_invalid = true; | 2161 | if (enum_type->data.enumeration.resolve_status != ResolveStatusInvalid) { |
| 2162 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; | ||
| 2163 | add_node_error(g, decl_node, | ||
| 2164 | buf_sprintf("enum '%s' depends on itself", | ||
| 2165 | buf_ptr(&enum_type->name))); | ||
| 2166 | } | ||
| 1939 | return ErrorSemanticAnalyzeFail; | 2167 | return ErrorSemanticAnalyzeFail; |
| 1940 | } | 2168 | } |
| 1941 | 2169 | ||
| 1942 | enum_type->data.enumeration.zero_bits_loop_flag = true; | 2170 | enum_type->data.enumeration.resolve_loop_flag = true; |
| 1943 | |||
| 1944 | AstNode *decl_node = enum_type->data.enumeration.decl_node; | ||
| 1945 | assert(decl_node->type == NodeTypeContainerDecl); | ||
| 1946 | 2171 | ||
| 1947 | assert(!enum_type->data.enumeration.fields); | 2172 | assert(!enum_type->data.enumeration.fields); |
| 1948 | uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length; | 2173 | uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length; |
| ... | @@ -1951,9 +2176,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -1951,9 +2176,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 1951 | 2176 | ||
| 1952 | enum_type->data.enumeration.src_field_count = field_count; | 2177 | enum_type->data.enumeration.src_field_count = field_count; |
| 1953 | enum_type->data.enumeration.fields = nullptr; | 2178 | enum_type->data.enumeration.fields = nullptr; |
| 1954 | enum_type->data.enumeration.is_invalid = true; | 2179 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 1955 | enum_type->data.enumeration.zero_bits_loop_flag = false; | ||
| 1956 | enum_type->data.enumeration.zero_bits_known = true; | ||
| 1957 | return ErrorSemanticAnalyzeFail; | 2180 | return ErrorSemanticAnalyzeFail; |
| 1958 | } | 2181 | } |
| 1959 | 2182 | ||
| ... | @@ -1982,14 +2205,14 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -1982,14 +2205,14 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 1982 | if (decl_node->data.container_decl.init_arg_expr != nullptr) { | 2205 | if (decl_node->data.container_decl.init_arg_expr != nullptr) { |
| 1983 | ZigType *wanted_tag_int_type = analyze_type_expr(g, scope, decl_node->data.container_decl.init_arg_expr); | 2206 | ZigType *wanted_tag_int_type = analyze_type_expr(g, scope, decl_node->data.container_decl.init_arg_expr); |
| 1984 | if (type_is_invalid(wanted_tag_int_type)) { | 2207 | if (type_is_invalid(wanted_tag_int_type)) { |
| 1985 | enum_type->data.enumeration.is_invalid = true; | 2208 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 1986 | } else if (wanted_tag_int_type->id != ZigTypeIdInt) { | 2209 | } else if (wanted_tag_int_type->id != ZigTypeIdInt) { |
| 1987 | enum_type->data.enumeration.is_invalid = true; | 2210 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 1988 | add_node_error(g, decl_node->data.container_decl.init_arg_expr, | 2211 | add_node_error(g, decl_node->data.container_decl.init_arg_expr, |
| 1989 | buf_sprintf("expected integer, found '%s'", buf_ptr(&wanted_tag_int_type->name))); | 2212 | buf_sprintf("expected integer, found '%s'", buf_ptr(&wanted_tag_int_type->name))); |
| 1990 | } else if (enum_type->data.enumeration.layout == ContainerLayoutExtern && | 2213 | } else if (enum_type->data.enumeration.layout == ContainerLayoutExtern && |
| 1991 | !type_is_valid_extern_enum_tag(g, wanted_tag_int_type)) { | 2214 | !type_is_valid_extern_enum_tag(g, wanted_tag_int_type)) { |
| 1992 | enum_type->data.enumeration.is_invalid = true; | 2215 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 1993 | ErrorMsg *msg = add_node_error(g, decl_node->data.container_decl.init_arg_expr, | 2216 | ErrorMsg *msg = add_node_error(g, decl_node->data.container_decl.init_arg_expr, |
| 1994 | buf_sprintf("'%s' is not a valid tag type for an extern enum", | 2217 | buf_sprintf("'%s' is not a valid tag type for an extern enum", |
| 1995 | buf_ptr(&wanted_tag_int_type->name))); | 2218 | buf_ptr(&wanted_tag_int_type->name))); |
| ... | @@ -2022,6 +2245,11 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2022,6 +2245,11 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2022 | buf_sprintf("structs and unions, not enums, support field types")); | 2245 | buf_sprintf("structs and unions, not enums, support field types")); |
| 2023 | add_error_note(g, msg, decl_node, | 2246 | add_error_note(g, msg, decl_node, |
| 2024 | buf_sprintf("consider 'union(enum)' here")); | 2247 | buf_sprintf("consider 'union(enum)' here")); |
| 2248 | } else if (field_node->data.struct_field.align_expr != nullptr) { | ||
| 2249 | ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.align_expr, | ||
| 2250 | buf_sprintf("structs and unions, not enums, support field alignment")); | ||
| 2251 | add_error_note(g, msg, decl_node, | ||
| 2252 | buf_sprintf("consider 'union(enum)' here")); | ||
| 2025 | } | 2253 | } |
| 2026 | 2254 | ||
| 2027 | auto field_entry = enum_type->data.enumeration.fields_by_name.put_unique(type_enum_field->name, type_enum_field); | 2255 | auto field_entry = enum_type->data.enumeration.fields_by_name.put_unique(type_enum_field->name, type_enum_field); |
| ... | @@ -2029,7 +2257,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2029,7 +2257,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2029 | ErrorMsg *msg = add_node_error(g, field_node, | 2257 | ErrorMsg *msg = add_node_error(g, field_node, |
| 2030 | buf_sprintf("duplicate enum field: '%s'", buf_ptr(type_enum_field->name))); | 2258 | buf_sprintf("duplicate enum field: '%s'", buf_ptr(type_enum_field->name))); |
| 2031 | add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here")); | 2259 | add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here")); |
| 2032 | enum_type->data.enumeration.is_invalid = true; | 2260 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2033 | continue; | 2261 | continue; |
| 2034 | } | 2262 | } |
| 2035 | 2263 | ||
| ... | @@ -2037,9 +2265,10 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2037,9 +2265,10 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2037 | 2265 | ||
| 2038 | if (tag_value != nullptr) { | 2266 | if (tag_value != nullptr) { |
| 2039 | // A user-specified value is available | 2267 | // A user-specified value is available |
| 2040 | ConstExprValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, nullptr); | 2268 | ConstExprValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, |
| 2269 | nullptr, UndefBad); | ||
| 2041 | if (type_is_invalid(result->type)) { | 2270 | if (type_is_invalid(result->type)) { |
| 2042 | enum_type->data.enumeration.is_invalid = true; | 2271 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2043 | continue; | 2272 | continue; |
| 2044 | } | 2273 | } |
| 2045 | 2274 | ||
| ... | @@ -2060,7 +2289,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2060,7 +2289,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2060 | if (!bigint_fits_in_bits(&type_enum_field->value, | 2289 | if (!bigint_fits_in_bits(&type_enum_field->value, |
| 2061 | tag_int_type->size_in_bits, | 2290 | tag_int_type->size_in_bits, |
| 2062 | tag_int_type->data.integral.is_signed)) { | 2291 | tag_int_type->data.integral.is_signed)) { |
| 2063 | enum_type->data.enumeration.is_invalid = true; | 2292 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2064 | 2293 | ||
| 2065 | Buf *val_buf = buf_alloc(); | 2294 | Buf *val_buf = buf_alloc(); |
| 2066 | bigint_append_buf(val_buf, &type_enum_field->value, 10); | 2295 | bigint_append_buf(val_buf, &type_enum_field->value, 10); |
| ... | @@ -2075,7 +2304,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2075,7 +2304,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2075 | // Make sure the value is unique | 2304 | // Make sure the value is unique |
| 2076 | auto entry = occupied_tag_values.put_unique(type_enum_field->value, field_node); | 2305 | auto entry = occupied_tag_values.put_unique(type_enum_field->value, field_node); |
| 2077 | if (entry != nullptr) { | 2306 | if (entry != nullptr) { |
| 2078 | enum_type->data.enumeration.is_invalid = true; | 2307 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2079 | 2308 | ||
| 2080 | Buf *val_buf = buf_alloc(); | 2309 | Buf *val_buf = buf_alloc(); |
| 2081 | bigint_append_buf(val_buf, &type_enum_field->value, 10); | 2310 | bigint_append_buf(val_buf, &type_enum_field->value, 10); |
| ... | @@ -2089,13 +2318,12 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2089,13 +2318,12 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2089 | last_enum_field = type_enum_field; | 2318 | last_enum_field = type_enum_field; |
| 2090 | } | 2319 | } |
| 2091 | 2320 | ||
| 2092 | enum_type->data.enumeration.zero_bits_loop_flag = false; | 2321 | if (enum_type->data.enumeration.resolve_status == ResolveStatusInvalid) |
| 2093 | enum_type->data.enumeration.zero_bits_known = true; | ||
| 2094 | enum_type->data.enumeration.complete = true; | ||
| 2095 | |||
| 2096 | if (enum_type->data.enumeration.is_invalid) | ||
| 2097 | return ErrorSemanticAnalyzeFail; | 2322 | return ErrorSemanticAnalyzeFail; |
| 2098 | 2323 | ||
| 2324 | enum_type->data.enumeration.resolve_loop_flag = false; | ||
| 2325 | enum_type->data.enumeration.resolve_status = ResolveStatusSizeKnown; | ||
| 2326 | |||
| 2099 | return ErrorNone; | 2327 | return ErrorNone; |
| 2100 | } | 2328 | } |
| 2101 | 2329 | ||
| ... | @@ -2112,16 +2340,17 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { | ... | @@ -2112,16 +2340,17 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { |
| 2112 | AstNode *decl_node = struct_type->data.structure.decl_node; | 2340 | AstNode *decl_node = struct_type->data.structure.decl_node; |
| 2113 | assert(decl_node->type == NodeTypeContainerDecl); | 2341 | assert(decl_node->type == NodeTypeContainerDecl); |
| 2114 | 2342 | ||
| 2115 | if (struct_type->data.structure.resolve_loop_flag) { | 2343 | if (struct_type->data.structure.resolve_loop_flag_zero_bits) { |
| 2116 | // TODO This is a problem. I believe it can be solved with lazy values. | 2344 | if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { |
| 2117 | struct_type->size_in_bits = SIZE_MAX; | 2345 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2118 | struct_type->abi_size = SIZE_MAX; | 2346 | add_node_error(g, decl_node, |
| 2119 | struct_type->data.structure.resolve_status = ResolveStatusZeroBitsKnown; | 2347 | buf_sprintf("struct '%s' depends on itself", |
| 2120 | struct_type->data.structure.resolve_loop_flag = false; | 2348 | buf_ptr(&struct_type->name))); |
| 2121 | return ErrorNone; | 2349 | } |
| 2350 | return ErrorSemanticAnalyzeFail; | ||
| 2122 | } | 2351 | } |
| 2123 | 2352 | ||
| 2124 | struct_type->data.structure.resolve_loop_flag = true; | 2353 | struct_type->data.structure.resolve_loop_flag_zero_bits = true; |
| 2125 | 2354 | ||
| 2126 | assert(!struct_type->data.structure.fields); | 2355 | assert(!struct_type->data.structure.fields); |
| 2127 | size_t field_count = decl_node->data.container_decl.fields.length; | 2356 | size_t field_count = decl_node->data.container_decl.fields.length; |
| ... | @@ -2153,58 +2382,60 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { | ... | @@ -2153,58 +2382,60 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { |
| 2153 | return ErrorSemanticAnalyzeFail; | 2382 | return ErrorSemanticAnalyzeFail; |
| 2154 | } | 2383 | } |
| 2155 | 2384 | ||
| 2156 | ZigType *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); | 2385 | ConstExprValue *field_type_val = analyze_const_value(g, scope, |
| 2157 | type_struct_field->type_entry = field_type; | 2386 | field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef); |
| 2158 | if (type_is_invalid(field_type)) { | 2387 | if (type_is_invalid(field_type_val->type)) { |
| 2159 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2388 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2160 | return ErrorSemanticAnalyzeFail; | 2389 | return ErrorSemanticAnalyzeFail; |
| 2161 | } | 2390 | } |
| 2391 | assert(field_type_val->special != ConstValSpecialRuntime); | ||
| 2392 | type_struct_field->type_val = field_type_val; | ||
| 2162 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) | 2393 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) |
| 2163 | return ErrorSemanticAnalyzeFail; | 2394 | return ErrorSemanticAnalyzeFail; |
| 2164 | 2395 | ||
| 2165 | if (struct_type->data.structure.layout == ContainerLayoutExtern && | 2396 | bool field_is_opaque_type; |
| 2166 | !type_allowed_in_extern(g, field_type)) | 2397 | if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) { |
| 2167 | { | ||
| 2168 | add_node_error(g, field_node, | ||
| 2169 | buf_sprintf("extern structs cannot contain fields of type '%s'", | ||
| 2170 | buf_ptr(&field_type->name))); | ||
| 2171 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2398 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2172 | return ErrorSemanticAnalyzeFail; | 2399 | return ErrorSemanticAnalyzeFail; |
| 2173 | } else if (struct_type->data.structure.layout == ContainerLayoutPacked) { | ||
| 2174 | if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field_type, field_node))) { | ||
| 2175 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 2176 | return ErrorSemanticAnalyzeFail; | ||
| 2177 | } | ||
| 2178 | } | 2400 | } |
| 2179 | 2401 | if (field_is_opaque_type) { | |
| 2180 | type_struct_field->src_index = i; | ||
| 2181 | type_struct_field->gen_index = SIZE_MAX; | ||
| 2182 | |||
| 2183 | if (field_type->id == ZigTypeIdOpaque) { | ||
| 2184 | add_node_error(g, field_node->data.struct_field.type, | 2402 | add_node_error(g, field_node->data.struct_field.type, |
| 2185 | buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs")); | 2403 | buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs")); |
| 2186 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2404 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2187 | return ErrorSemanticAnalyzeFail; | 2405 | return ErrorSemanticAnalyzeFail; |
| 2188 | } | 2406 | } |
| 2189 | switch (type_requires_comptime(g, field_type)) { | 2407 | |
| 2408 | type_struct_field->src_index = i; | ||
| 2409 | type_struct_field->gen_index = SIZE_MAX; | ||
| 2410 | |||
| 2411 | switch (type_val_resolve_requires_comptime(g, field_type_val)) { | ||
| 2190 | case ReqCompTimeYes: | 2412 | case ReqCompTimeYes: |
| 2191 | struct_type->data.structure.requires_comptime = true; | 2413 | struct_type->data.structure.requires_comptime = true; |
| 2192 | break; | 2414 | break; |
| 2193 | case ReqCompTimeInvalid: | 2415 | case ReqCompTimeInvalid: |
| 2416 | if (g->trace_err != nullptr) { | ||
| 2417 | g->trace_err = add_error_note(g, g->trace_err, field_node, | ||
| 2418 | buf_create_from_str("while checking this field")); | ||
| 2419 | } | ||
| 2194 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2420 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2195 | return ErrorSemanticAnalyzeFail; | 2421 | return ErrorSemanticAnalyzeFail; |
| 2196 | case ReqCompTimeNo: | 2422 | case ReqCompTimeNo: |
| 2197 | break; | 2423 | break; |
| 2198 | } | 2424 | } |
| 2199 | 2425 | ||
| 2200 | if (!type_has_bits(field_type)) | 2426 | bool field_is_zero_bits; |
| 2427 | if ((err = type_val_resolve_zero_bits(g, field_type_val, struct_type, nullptr, &field_is_zero_bits))) { | ||
| 2428 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | ||
| 2429 | return ErrorSemanticAnalyzeFail; | ||
| 2430 | } | ||
| 2431 | if (field_is_zero_bits) | ||
| 2201 | continue; | 2432 | continue; |
| 2202 | 2433 | ||
| 2203 | type_struct_field->gen_index = gen_field_index; | 2434 | type_struct_field->gen_index = gen_field_index; |
| 2204 | gen_field_index += 1; | 2435 | gen_field_index += 1; |
| 2205 | } | 2436 | } |
| 2206 | 2437 | ||
| 2207 | struct_type->data.structure.resolve_loop_flag = false; | 2438 | struct_type->data.structure.resolve_loop_flag_zero_bits = false; |
| 2208 | struct_type->data.structure.gen_field_count = (uint32_t)gen_field_index; | 2439 | struct_type->data.structure.gen_field_count = (uint32_t)gen_field_index; |
| 2209 | if (gen_field_index != 0) { | 2440 | if (gen_field_index != 0) { |
| 2210 | struct_type->abi_size = SIZE_MAX; | 2441 | struct_type->abi_size = SIZE_MAX; |
| ... | @@ -2234,17 +2465,16 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { | ... | @@ -2234,17 +2465,16 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2234 | 2465 | ||
| 2235 | AstNode *decl_node = struct_type->data.structure.decl_node; | 2466 | AstNode *decl_node = struct_type->data.structure.decl_node; |
| 2236 | 2467 | ||
| 2237 | if (struct_type->data.structure.resolve_loop_flag) { | 2468 | if (struct_type->data.structure.resolve_loop_flag_other) { |
| 2238 | if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { | 2469 | if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { |
| 2239 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2470 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2240 | ErrorMsg *msg = add_node_error(g, decl_node, | 2471 | add_node_error(g, decl_node, |
| 2241 | buf_sprintf("struct '%s' contains itself", buf_ptr(&struct_type->name))); | 2472 | buf_sprintf("struct '%s' depends on itself", buf_ptr(&struct_type->name))); |
| 2242 | emit_error_notes_for_ref_stack(g, msg); | ||
| 2243 | } | 2473 | } |
| 2244 | return ErrorSemanticAnalyzeFail; | 2474 | return ErrorSemanticAnalyzeFail; |
| 2245 | } | 2475 | } |
| 2246 | 2476 | ||
| 2247 | struct_type->data.structure.resolve_loop_flag = true; | 2477 | struct_type->data.structure.resolve_loop_flag_other = true; |
| 2248 | assert(decl_node->type == NodeTypeContainerDecl); | 2478 | assert(decl_node->type == NodeTypeContainerDecl); |
| 2249 | 2479 | ||
| 2250 | size_t field_count = struct_type->data.structure.src_field_count; | 2480 | size_t field_count = struct_type->data.structure.src_field_count; |
| ... | @@ -2255,47 +2485,31 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { | ... | @@ -2255,47 +2485,31 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2255 | if (field->gen_index == SIZE_MAX) | 2485 | if (field->gen_index == SIZE_MAX) |
| 2256 | continue; | 2486 | continue; |
| 2257 | 2487 | ||
| 2258 | uint32_t this_field_align; | ||
| 2259 | |||
| 2260 | // TODO: Sets the field alignment in the type, but doesn't do anything | ||
| 2261 | // to actually make that happen yet. | ||
| 2262 | AstNode *align_expr = field->decl_node->data.struct_field.align_expr; | 2488 | AstNode *align_expr = field->decl_node->data.struct_field.align_expr; |
| 2263 | if (align_expr != nullptr) { | 2489 | if (align_expr != nullptr) { |
| 2264 | if (!analyze_const_align(g, &struct_type->data.structure.decls_scope->base, align_expr, &this_field_align)) { | 2490 | if (!analyze_const_align(g, &struct_type->data.structure.decls_scope->base, align_expr, |
| 2265 | field->type_entry = g->builtin_types.entry_invalid; | 2491 | &field->align)) |
| 2266 | } else { | 2492 | { |
| 2267 | field->align = this_field_align; | 2493 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2494 | return err; | ||
| 2268 | } | 2495 | } |
| 2269 | } else if (packed) { | 2496 | } else if (packed) { |
| 2270 | // TODO: https://github.com/ziglang/zig/issues/1512 | 2497 | field->align = 1; |
| 2271 | // TODO: Validate requested alignment is possible, given packed, | ||
| 2272 | // and given other field alignments. | ||
| 2273 | this_field_align = 1; | ||
| 2274 | // TODO If we have no type_entry for the field, we've already failed to | ||
| 2275 | // compile the program correctly. This stage1 compiler needs a deeper | ||
| 2276 | // reworking to make this correct, or we can ignore the problem | ||
| 2277 | // and make sure it is fixed in stage2. This workaround is for when | ||
| 2278 | // there is a false positive of a dependency loop, of alignment depending | ||
| 2279 | // on itself. When this false positive happens we assume a pointer-aligned | ||
| 2280 | // field, which is usually fine but could be incorrectly over-aligned or | ||
| 2281 | // even under-aligned. See https://github.com/ziglang/zig/issues/1512 | ||
| 2282 | } else if (field->type_entry == nullptr) { | ||
| 2283 | this_field_align = g->builtin_types.entry_usize->abi_align; | ||
| 2284 | } else { | 2498 | } else { |
| 2285 | if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) { | 2499 | if ((err = type_val_resolve_abi_align(g, field->type_val, &field->align))) { |
| 2286 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2500 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2287 | return ErrorSemanticAnalyzeFail; | 2501 | return err; |
| 2288 | } | 2502 | } |
| 2289 | this_field_align = field->type_entry->abi_align; | 2503 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) |
| 2504 | return ErrorSemanticAnalyzeFail; | ||
| 2290 | } | 2505 | } |
| 2291 | 2506 | ||
| 2292 | // TODO: https://github.com/ziglang/zig/issues/1512 | 2507 | if (field->align > struct_type->abi_align) { |
| 2293 | if (this_field_align > struct_type->abi_align) { | 2508 | struct_type->abi_align = field->align; |
| 2294 | struct_type->abi_align = this_field_align; | ||
| 2295 | } | 2509 | } |
| 2296 | } | 2510 | } |
| 2297 | 2511 | ||
| 2298 | struct_type->data.structure.resolve_loop_flag = false; | 2512 | struct_type->data.structure.resolve_loop_flag_other = false; |
| 2299 | 2513 | ||
| 2300 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) { | 2514 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) { |
| 2301 | return ErrorSemanticAnalyzeFail; | 2515 | return ErrorSemanticAnalyzeFail; |
| ... | @@ -2316,23 +2530,21 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { | ... | @@ -2316,23 +2530,21 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 2316 | if (union_type->data.unionation.resolve_status >= ResolveStatusZeroBitsKnown) | 2530 | if (union_type->data.unionation.resolve_status >= ResolveStatusZeroBitsKnown) |
| 2317 | return ErrorNone; | 2531 | return ErrorNone; |
| 2318 | 2532 | ||
| 2319 | if (union_type->data.unionation.resolve_loop_flag) { | ||
| 2320 | // If we get here it's due to recursion. From this we conclude that the struct is | ||
| 2321 | // not zero bits. | ||
| 2322 | // TODO actually it could still be zero bits. Here we should continue analyzing | ||
| 2323 | // the union from the next field index. | ||
| 2324 | union_type->data.unionation.resolve_status = ResolveStatusZeroBitsKnown; | ||
| 2325 | union_type->data.unionation.resolve_loop_flag = false; | ||
| 2326 | union_type->abi_size = SIZE_MAX; | ||
| 2327 | union_type->size_in_bits = SIZE_MAX; | ||
| 2328 | return ErrorNone; | ||
| 2329 | } | ||
| 2330 | |||
| 2331 | union_type->data.unionation.resolve_loop_flag = true; | ||
| 2332 | |||
| 2333 | AstNode *decl_node = union_type->data.unionation.decl_node; | 2533 | AstNode *decl_node = union_type->data.unionation.decl_node; |
| 2334 | assert(decl_node->type == NodeTypeContainerDecl); | 2534 | assert(decl_node->type == NodeTypeContainerDecl); |
| 2335 | 2535 | ||
| 2536 | if (union_type->data.unionation.resolve_loop_flag_zero_bits) { | ||
| 2537 | if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) { | ||
| 2538 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | ||
| 2539 | add_node_error(g, decl_node, | ||
| 2540 | buf_sprintf("union '%s' depends on itself", | ||
| 2541 | buf_ptr(&union_type->name))); | ||
| 2542 | } | ||
| 2543 | return ErrorSemanticAnalyzeFail; | ||
| 2544 | } | ||
| 2545 | |||
| 2546 | union_type->data.unionation.resolve_loop_flag_zero_bits = true; | ||
| 2547 | |||
| 2336 | assert(union_type->data.unionation.fields == nullptr); | 2548 | assert(union_type->data.unionation.fields == nullptr); |
| 2337 | uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length; | 2549 | uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length; |
| 2338 | if (field_count == 0) { | 2550 | if (field_count == 0) { |
| ... | @@ -2392,14 +2604,13 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { | ... | @@ -2392,14 +2604,13 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 2392 | tag_type->size_in_bits = tag_int_type->size_in_bits; | 2604 | tag_type->size_in_bits = tag_int_type->size_in_bits; |
| 2393 | 2605 | ||
| 2394 | tag_type->data.enumeration.tag_int_type = tag_int_type; | 2606 | tag_type->data.enumeration.tag_int_type = tag_int_type; |
| 2395 | tag_type->data.enumeration.zero_bits_known = true; | 2607 | tag_type->data.enumeration.resolve_status = ResolveStatusSizeKnown; |
| 2396 | tag_type->data.enumeration.decl_node = decl_node; | 2608 | tag_type->data.enumeration.decl_node = decl_node; |
| 2397 | tag_type->data.enumeration.layout = ContainerLayoutAuto; | 2609 | tag_type->data.enumeration.layout = ContainerLayoutAuto; |
| 2398 | tag_type->data.enumeration.src_field_count = field_count; | 2610 | tag_type->data.enumeration.src_field_count = field_count; |
| 2399 | tag_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); | 2611 | tag_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); |
| 2400 | tag_type->data.enumeration.fields_by_name.init(field_count); | 2612 | tag_type->data.enumeration.fields_by_name.init(field_count); |
| 2401 | tag_type->data.enumeration.decls_scope = union_type->data.unionation.decls_scope; | 2613 | tag_type->data.enumeration.decls_scope = union_type->data.unionation.decls_scope; |
| 2402 | tag_type->data.enumeration.complete = true; | ||
| 2403 | } else if (enum_type_node != nullptr) { | 2614 | } else if (enum_type_node != nullptr) { |
| 2404 | ZigType *enum_type = analyze_type_expr(g, scope, enum_type_node); | 2615 | ZigType *enum_type = analyze_type_expr(g, scope, enum_type_node); |
| 2405 | if (type_is_invalid(enum_type)) { | 2616 | if (type_is_invalid(enum_type)) { |
| ... | @@ -2441,49 +2652,68 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { | ... | @@ -2441,49 +2652,68 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 2441 | return ErrorSemanticAnalyzeFail; | 2652 | return ErrorSemanticAnalyzeFail; |
| 2442 | } | 2653 | } |
| 2443 | 2654 | ||
| 2444 | ZigType *field_type; | 2655 | bool field_is_zero_bits; |
| 2445 | if (field_node->data.struct_field.type == nullptr) { | 2656 | if (field_node->data.struct_field.type == nullptr) { |
| 2446 | if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) { | 2657 | if (decl_node->data.container_decl.auto_enum || |
| 2447 | field_type = g->builtin_types.entry_void; | 2658 | decl_node->data.container_decl.init_arg_expr != nullptr) |
| 2659 | { | ||
| 2660 | union_field->type_entry = g->builtin_types.entry_void; | ||
| 2661 | field_is_zero_bits = true; | ||
| 2448 | } else { | 2662 | } else { |
| 2449 | add_node_error(g, field_node, buf_sprintf("union field missing type")); | 2663 | add_node_error(g, field_node, buf_sprintf("union field missing type")); |
| 2450 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2664 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2451 | return ErrorSemanticAnalyzeFail; | 2665 | return ErrorSemanticAnalyzeFail; |
| 2452 | } | 2666 | } |
| 2453 | } else { | 2667 | } else { |
| 2454 | field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); | 2668 | ConstExprValue *field_type_val = analyze_const_value(g, scope, |
| 2455 | if ((err = type_resolve(g, field_type, ResolveStatusAlignmentKnown))) { | 2669 | field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef); |
| 2670 | if (type_is_invalid(field_type_val->type)) { | ||
| 2456 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2671 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2457 | return ErrorSemanticAnalyzeFail; | 2672 | return ErrorSemanticAnalyzeFail; |
| 2458 | } | 2673 | } |
| 2674 | assert(field_type_val->special != ConstValSpecialRuntime); | ||
| 2675 | union_field->type_val = field_type_val; | ||
| 2459 | if (union_type->data.unionation.resolve_status == ResolveStatusInvalid) | 2676 | if (union_type->data.unionation.resolve_status == ResolveStatusInvalid) |
| 2460 | return ErrorSemanticAnalyzeFail; | 2677 | return ErrorSemanticAnalyzeFail; |
| 2461 | } | ||
| 2462 | union_field->type_entry = field_type; | ||
| 2463 | 2678 | ||
| 2464 | if (field_type->id == ZigTypeIdOpaque) { | 2679 | bool field_is_opaque_type; |
| 2465 | add_node_error(g, field_node->data.struct_field.type, | 2680 | if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) { |
| 2466 | buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in unions")); | 2681 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2467 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2682 | return ErrorSemanticAnalyzeFail; |
| 2468 | return ErrorSemanticAnalyzeFail; | 2683 | } |
| 2469 | } | 2684 | if (field_is_opaque_type) { |
| 2685 | add_node_error(g, field_node->data.struct_field.type, | ||
| 2686 | buf_create_from_str( | ||
| 2687 | "opaque types have unknown size and therefore cannot be directly embedded in unions")); | ||
| 2688 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | ||
| 2689 | return ErrorSemanticAnalyzeFail; | ||
| 2690 | } | ||
| 2470 | 2691 | ||
| 2471 | switch (type_requires_comptime(g, field_type)) { | 2692 | switch (type_val_resolve_requires_comptime(g, field_type_val)) { |
| 2472 | case ReqCompTimeInvalid: | 2693 | case ReqCompTimeInvalid: |
| 2694 | if (g->trace_err != nullptr) { | ||
| 2695 | g->trace_err = add_error_note(g, g->trace_err, field_node, | ||
| 2696 | buf_create_from_str("while checking this field")); | ||
| 2697 | } | ||
| 2698 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | ||
| 2699 | return ErrorSemanticAnalyzeFail; | ||
| 2700 | case ReqCompTimeYes: | ||
| 2701 | union_type->data.unionation.requires_comptime = true; | ||
| 2702 | break; | ||
| 2703 | case ReqCompTimeNo: | ||
| 2704 | break; | ||
| 2705 | } | ||
| 2706 | |||
| 2707 | if ((err = type_val_resolve_zero_bits(g, field_type_val, union_type, nullptr, &field_is_zero_bits))) { | ||
| 2473 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2708 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2474 | return ErrorSemanticAnalyzeFail; | 2709 | return ErrorSemanticAnalyzeFail; |
| 2475 | case ReqCompTimeYes: | 2710 | } |
| 2476 | union_type->data.unionation.requires_comptime = true; | ||
| 2477 | break; | ||
| 2478 | case ReqCompTimeNo: | ||
| 2479 | break; | ||
| 2480 | } | 2711 | } |
| 2481 | 2712 | ||
| 2482 | if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) { | 2713 | if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) { |
| 2483 | ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value, | 2714 | ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value, |
| 2484 | buf_sprintf("non-enum union field assignment")); | 2715 | buf_create_from_str("untagged union field assignment")); |
| 2485 | add_error_note(g, msg, decl_node, | 2716 | add_error_note(g, msg, decl_node, buf_create_from_str("consider 'union(enum)' here")); |
| 2486 | buf_sprintf("consider 'union(enum)' here")); | ||
| 2487 | } | 2717 | } |
| 2488 | 2718 | ||
| 2489 | if (create_enum_type) { | 2719 | if (create_enum_type) { |
| ... | @@ -2501,7 +2731,8 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { | ... | @@ -2501,7 +2731,8 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 2501 | // In a second pass we will fill in the unspecified ones. | 2731 | // In a second pass we will fill in the unspecified ones. |
| 2502 | if (tag_value != nullptr) { | 2732 | if (tag_value != nullptr) { |
| 2503 | ZigType *tag_int_type = tag_type->data.enumeration.tag_int_type; | 2733 | ZigType *tag_int_type = tag_type->data.enumeration.tag_int_type; |
| 2504 | ConstExprValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, nullptr); | 2734 | ConstExprValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, |
| 2735 | nullptr, UndefBad); | ||
| 2505 | if (type_is_invalid(result->type)) { | 2736 | if (type_is_invalid(result->type)) { |
| 2506 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | 2737 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2507 | return ErrorSemanticAnalyzeFail; | 2738 | return ErrorSemanticAnalyzeFail; |
| ... | @@ -2542,7 +2773,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { | ... | @@ -2542,7 +2773,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 2542 | } | 2773 | } |
| 2543 | assert(union_field->enum_field != nullptr); | 2774 | assert(union_field->enum_field != nullptr); |
| 2544 | 2775 | ||
| 2545 | if (!type_has_bits(field_type)) | 2776 | if (field_is_zero_bits) |
| 2546 | continue; | 2777 | continue; |
| 2547 | 2778 | ||
| 2548 | union_field->gen_index = gen_field_index; | 2779 | union_field->gen_index = gen_field_index; |
| ... | @@ -2619,7 +2850,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { | ... | @@ -2619,7 +2850,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 2619 | return ErrorSemanticAnalyzeFail; | 2850 | return ErrorSemanticAnalyzeFail; |
| 2620 | } | 2851 | } |
| 2621 | 2852 | ||
| 2622 | union_type->data.unionation.resolve_loop_flag = false; | 2853 | union_type->data.unionation.resolve_loop_flag_zero_bits = false; |
| 2623 | 2854 | ||
| 2624 | union_type->data.unionation.gen_field_count = gen_field_index; | 2855 | union_type->data.unionation.gen_field_count = gen_field_index; |
| 2625 | bool zero_bits = gen_field_index == 0 && (field_count < 2 || !src_have_tag); | 2856 | bool zero_bits = gen_field_index == 0 && (field_count < 2 || !src_have_tag); |
| ... | @@ -2676,6 +2907,8 @@ ZigFn *create_fn(CodeGen *g, AstNode *proto_node) { | ... | @@ -2676,6 +2907,8 @@ ZigFn *create_fn(CodeGen *g, AstNode *proto_node) { |
| 2676 | fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr : | 2907 | fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr : |
| 2677 | proto_node->data.fn_proto.fn_def_node->data.fn_def.body; | 2908 | proto_node->data.fn_proto.fn_def_node->data.fn_def.body; |
| 2678 | 2909 | ||
| 2910 | fn_entry->analyzed_executable.source_node = fn_entry->body_node; | ||
| 2911 | |||
| 2679 | return fn_entry; | 2912 | return fn_entry; |
| 2680 | } | 2913 | } |
| 2681 | 2914 | ||
| ... | @@ -2702,7 +2935,7 @@ void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn) { | ... | @@ -2702,7 +2935,7 @@ void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn) { |
| 2702 | fake_decl->data.symbol_expr.symbol = tld_fn->base.name; | 2935 | fake_decl->data.symbol_expr.symbol = tld_fn->base.name; |
| 2703 | 2936 | ||
| 2704 | // call this for the side effects of casting to panic_fn_type | 2937 | // call this for the side effects of casting to panic_fn_type |
| 2705 | analyze_const_value(g, tld_fn->base.parent_scope, fake_decl, panic_fn_type, nullptr); | 2938 | analyze_const_value(g, tld_fn->base.parent_scope, fake_decl, panic_fn_type, nullptr, UndefBad); |
| 2706 | } | 2939 | } |
| 2707 | 2940 | ||
| 2708 | ZigType *get_test_fn_type(CodeGen *g) { | 2941 | ZigType *get_test_fn_type(CodeGen *g) { |
| ... | @@ -2848,7 +3081,8 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -2848,7 +3081,8 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2848 | static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) { | 3081 | static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) { |
| 2849 | assert(tld_comptime->base.source_node->type == NodeTypeCompTime); | 3082 | assert(tld_comptime->base.source_node->type == NodeTypeCompTime); |
| 2850 | AstNode *expr_node = tld_comptime->base.source_node->data.comptime_expr.expr; | 3083 | AstNode *expr_node = tld_comptime->base.source_node->data.comptime_expr.expr; |
| 2851 | analyze_const_value(g, tld_comptime->base.parent_scope, expr_node, g->builtin_types.entry_void, nullptr); | 3084 | analyze_const_value(g, tld_comptime->base.parent_scope, expr_node, g->builtin_types.entry_void, |
| 3085 | nullptr, UndefBad); | ||
| 2852 | } | 3086 | } |
| 2853 | 3087 | ||
| 2854 | static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { | 3088 | static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { |
| ... | @@ -2943,7 +3177,7 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source | ... | @@ -2943,7 +3177,7 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source |
| 2943 | 3177 | ||
| 2944 | void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) { | 3178 | void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) { |
| 2945 | Tld *tld = get_container_scope(g->compile_var_import)->decl_table.get(name); | 3179 | Tld *tld = get_container_scope(g->compile_var_import)->decl_table.get(name); |
| 2946 | resolve_top_level_decl(g, tld, tld->source_node); | 3180 | resolve_top_level_decl(g, tld, tld->source_node, false); |
| 2947 | assert(tld->id == TldIdVar); | 3181 | assert(tld->id == TldIdVar); |
| 2948 | TldVar *tld_var = (TldVar *)tld; | 3182 | TldVar *tld_var = (TldVar *)tld; |
| 2949 | tld_var->var->const_value = value; | 3183 | tld_var->var->const_value = value; |
| ... | @@ -3185,7 +3419,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf | ... | @@ -3185,7 +3419,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf |
| 3185 | return variable_entry; | 3419 | return variable_entry; |
| 3186 | } | 3420 | } |
| 3187 | 3421 | ||
| 3188 | static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | 3422 | static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) { |
| 3189 | AstNode *source_node = tld_var->base.source_node; | 3423 | AstNode *source_node = tld_var->base.source_node; |
| 3190 | AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration; | 3424 | AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration; |
| 3191 | 3425 | ||
| ... | @@ -3197,9 +3431,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | ... | @@ -3197,9 +3431,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 3197 | ZigType *explicit_type = nullptr; | 3431 | ZigType *explicit_type = nullptr; |
| 3198 | if (var_decl->type) { | 3432 | if (var_decl->type) { |
| 3199 | if (tld_var->analyzing_type) { | 3433 | if (tld_var->analyzing_type) { |
| 3200 | ErrorMsg *msg = add_node_error(g, var_decl->type, | 3434 | add_node_error(g, var_decl->type, |
| 3201 | buf_sprintf("type of '%s' depends on itself", buf_ptr(tld_var->base.name))); | 3435 | buf_sprintf("type of '%s' depends on itself", buf_ptr(tld_var->base.name))); |
| 3202 | emit_error_notes_for_ref_stack(g, msg); | ||
| 3203 | explicit_type = g->builtin_types.entry_invalid; | 3436 | explicit_type = g->builtin_types.entry_invalid; |
| 3204 | } else { | 3437 | } else { |
| 3205 | tld_var->analyzing_type = true; | 3438 | tld_var->analyzing_type = true; |
| ... | @@ -3217,7 +3450,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | ... | @@ -3217,7 +3450,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 3217 | if (explicit_type && explicit_type->id == ZigTypeIdInvalid) { | 3450 | if (explicit_type && explicit_type->id == ZigTypeIdInvalid) { |
| 3218 | implicit_type = explicit_type; | 3451 | implicit_type = explicit_type; |
| 3219 | } else if (var_decl->expr) { | 3452 | } else if (var_decl->expr) { |
| 3220 | init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, var_decl->symbol); | 3453 | init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, |
| 3454 | var_decl->symbol, allow_lazy ? LazyOk : UndefOk); | ||
| 3221 | assert(init_value); | 3455 | assert(init_value); |
| 3222 | implicit_type = init_value->type; | 3456 | implicit_type = init_value->type; |
| 3223 | 3457 | ||
| ... | @@ -3372,7 +3606,8 @@ static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, Sco | ... | @@ -3372,7 +3606,8 @@ static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, Sco |
| 3372 | using_namespace->base.resolution = TldResolutionResolving; | 3606 | using_namespace->base.resolution = TldResolutionResolving; |
| 3373 | assert(using_namespace->base.source_node->type == NodeTypeUsingNamespace); | 3607 | assert(using_namespace->base.source_node->type == NodeTypeUsingNamespace); |
| 3374 | ConstExprValue *result = analyze_const_value(g, &dest_decls_scope->base, | 3608 | ConstExprValue *result = analyze_const_value(g, &dest_decls_scope->base, |
| 3375 | using_namespace->base.source_node->data.using_namespace.expr, g->builtin_types.entry_type, nullptr); | 3609 | using_namespace->base.source_node->data.using_namespace.expr, g->builtin_types.entry_type, |
| 3610 | nullptr, UndefBad); | ||
| 3376 | using_namespace->using_namespace_value = result; | 3611 | using_namespace->using_namespace_value = result; |
| 3377 | 3612 | ||
| 3378 | if (type_is_invalid(result->type)) { | 3613 | if (type_is_invalid(result->type)) { |
| ... | @@ -3392,51 +3627,61 @@ static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, Sco | ... | @@ -3392,51 +3627,61 @@ static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, Sco |
| 3392 | } | 3627 | } |
| 3393 | } | 3628 | } |
| 3394 | 3629 | ||
| 3395 | void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { | 3630 | void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool allow_lazy) { |
| 3396 | if (tld->resolution != TldResolutionUnresolved) | 3631 | bool want_resolve_lazy = tld->resolution == TldResolutionOkLazy && !allow_lazy; |
| 3632 | if (tld->resolution != TldResolutionUnresolved && !want_resolve_lazy) | ||
| 3397 | return; | 3633 | return; |
| 3398 | 3634 | ||
| 3399 | assert(tld->resolution != TldResolutionResolving); | ||
| 3400 | tld->resolution = TldResolutionResolving; | 3635 | tld->resolution = TldResolutionResolving; |
| 3401 | g->tld_ref_source_node_stack.append(source_node); | ||
| 3402 | 3636 | ||
| 3403 | switch (tld->id) { | 3637 | switch (tld->id) { |
| 3404 | case TldIdVar: | 3638 | case TldIdVar: { |
| 3405 | { | 3639 | TldVar *tld_var = (TldVar *)tld; |
| 3406 | TldVar *tld_var = (TldVar *)tld; | 3640 | if (want_resolve_lazy) { |
| 3407 | resolve_decl_var(g, tld_var); | 3641 | ir_resolve_lazy(g, source_node, tld_var->var->const_value); |
| 3408 | break; | 3642 | } else { |
| 3409 | } | 3643 | resolve_decl_var(g, tld_var, allow_lazy); |
| 3410 | case TldIdFn: | ||
| 3411 | { | ||
| 3412 | TldFn *tld_fn = (TldFn *)tld; | ||
| 3413 | resolve_decl_fn(g, tld_fn); | ||
| 3414 | break; | ||
| 3415 | } | ||
| 3416 | case TldIdContainer: | ||
| 3417 | { | ||
| 3418 | TldContainer *tld_container = (TldContainer *)tld; | ||
| 3419 | resolve_decl_container(g, tld_container); | ||
| 3420 | break; | ||
| 3421 | } | ||
| 3422 | case TldIdCompTime: | ||
| 3423 | { | ||
| 3424 | TldCompTime *tld_comptime = (TldCompTime *)tld; | ||
| 3425 | resolve_decl_comptime(g, tld_comptime); | ||
| 3426 | break; | ||
| 3427 | } | 3644 | } |
| 3645 | tld->resolution = allow_lazy ? TldResolutionOkLazy : TldResolutionOk; | ||
| 3646 | break; | ||
| 3647 | } | ||
| 3648 | case TldIdFn: { | ||
| 3649 | TldFn *tld_fn = (TldFn *)tld; | ||
| 3650 | resolve_decl_fn(g, tld_fn); | ||
| 3651 | |||
| 3652 | tld->resolution = TldResolutionOk; | ||
| 3653 | break; | ||
| 3654 | } | ||
| 3655 | case TldIdContainer: { | ||
| 3656 | TldContainer *tld_container = (TldContainer *)tld; | ||
| 3657 | resolve_decl_container(g, tld_container); | ||
| 3658 | |||
| 3659 | tld->resolution = TldResolutionOk; | ||
| 3660 | break; | ||
| 3661 | } | ||
| 3662 | case TldIdCompTime: { | ||
| 3663 | TldCompTime *tld_comptime = (TldCompTime *)tld; | ||
| 3664 | resolve_decl_comptime(g, tld_comptime); | ||
| 3665 | |||
| 3666 | tld->resolution = TldResolutionOk; | ||
| 3667 | break; | ||
| 3668 | } | ||
| 3428 | case TldIdUsingNamespace: { | 3669 | case TldIdUsingNamespace: { |
| 3429 | TldUsingNamespace *tld_using_namespace = (TldUsingNamespace *)tld; | 3670 | TldUsingNamespace *tld_using_namespace = (TldUsingNamespace *)tld; |
| 3430 | assert(tld_using_namespace->base.parent_scope->id == ScopeIdDecls); | 3671 | assert(tld_using_namespace->base.parent_scope->id == ScopeIdDecls); |
| 3431 | ScopeDecls *dest_decls_scope = (ScopeDecls *)tld_using_namespace->base.parent_scope; | 3672 | ScopeDecls *dest_decls_scope = (ScopeDecls *)tld_using_namespace->base.parent_scope; |
| 3432 | preview_use_decl(g, tld_using_namespace, dest_decls_scope); | 3673 | preview_use_decl(g, tld_using_namespace, dest_decls_scope); |
| 3433 | resolve_use_decl(g, tld_using_namespace, dest_decls_scope); | 3674 | resolve_use_decl(g, tld_using_namespace, dest_decls_scope); |
| 3675 | |||
| 3676 | tld->resolution = TldResolutionOk; | ||
| 3434 | break; | 3677 | break; |
| 3435 | } | 3678 | } |
| 3436 | } | 3679 | } |
| 3437 | 3680 | ||
| 3438 | tld->resolution = TldResolutionOk; | 3681 | if (g->trace_err != nullptr && source_node != nullptr && !source_node->already_traced_this_node) { |
| 3439 | g->tld_ref_source_node_stack.pop(); | 3682 | g->trace_err = add_error_note(g, g->trace_err, source_node, buf_create_from_str("referenced here")); |
| 3683 | source_node->already_traced_this_node = true; | ||
| 3684 | } | ||
| 3440 | } | 3685 | } |
| 3441 | 3686 | ||
| 3442 | Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) { | 3687 | Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) { |
| ... | @@ -3562,7 +3807,7 @@ TypeUnionField *find_union_field_by_tag(ZigType *type_entry, const BigInt *tag) | ... | @@ -3562,7 +3807,7 @@ TypeUnionField *find_union_field_by_tag(ZigType *type_entry, const BigInt *tag) |
| 3562 | } | 3807 | } |
| 3563 | 3808 | ||
| 3564 | TypeEnumField *find_enum_field_by_tag(ZigType *enum_type, const BigInt *tag) { | 3809 | TypeEnumField *find_enum_field_by_tag(ZigType *enum_type, const BigInt *tag) { |
| 3565 | assert(enum_type->data.enumeration.zero_bits_known); | 3810 | assert(type_is_resolved(enum_type, ResolveStatusZeroBitsKnown)); |
| 3566 | for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) { | 3811 | for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) { |
| 3567 | TypeEnumField *field = &enum_type->data.enumeration.fields[i]; | 3812 | TypeEnumField *field = &enum_type->data.enumeration.fields[i]; |
| 3568 | if (bigint_cmp(&field->value, tag) == CmpEQ) { | 3813 | if (bigint_cmp(&field->value, tag) == CmpEQ) { |
| ... | @@ -3631,43 +3876,6 @@ ZigType *container_ref_type(ZigType *type_entry) { | ... | @@ -3631,43 +3876,6 @@ ZigType *container_ref_type(ZigType *type_entry) { |
| 3631 | type_entry->data.pointer.child_type : type_entry; | 3876 | type_entry->data.pointer.child_type : type_entry; |
| 3632 | } | 3877 | } |
| 3633 | 3878 | ||
| 3634 | Error resolve_container_type(CodeGen *g, ZigType *type_entry) { | ||
| 3635 | switch (type_entry->id) { | ||
| 3636 | case ZigTypeIdStruct: | ||
| 3637 | return resolve_struct_type(g, type_entry); | ||
| 3638 | case ZigTypeIdEnum: | ||
| 3639 | return resolve_enum_zero_bits(g, type_entry); | ||
| 3640 | case ZigTypeIdUnion: | ||
| 3641 | return resolve_union_type(g, type_entry); | ||
| 3642 | case ZigTypeIdPointer: | ||
| 3643 | case ZigTypeIdMetaType: | ||
| 3644 | case ZigTypeIdVoid: | ||
| 3645 | case ZigTypeIdBool: | ||
| 3646 | case ZigTypeIdUnreachable: | ||
| 3647 | case ZigTypeIdInt: | ||
| 3648 | case ZigTypeIdFloat: | ||
| 3649 | case ZigTypeIdArray: | ||
| 3650 | case ZigTypeIdComptimeFloat: | ||
| 3651 | case ZigTypeIdComptimeInt: | ||
| 3652 | case ZigTypeIdEnumLiteral: | ||
| 3653 | case ZigTypeIdUndefined: | ||
| 3654 | case ZigTypeIdNull: | ||
| 3655 | case ZigTypeIdOptional: | ||
| 3656 | case ZigTypeIdErrorUnion: | ||
| 3657 | case ZigTypeIdErrorSet: | ||
| 3658 | case ZigTypeIdFn: | ||
| 3659 | case ZigTypeIdBoundFn: | ||
| 3660 | case ZigTypeIdInvalid: | ||
| 3661 | case ZigTypeIdArgTuple: | ||
| 3662 | case ZigTypeIdOpaque: | ||
| 3663 | case ZigTypeIdVector: | ||
| 3664 | case ZigTypeIdFnFrame: | ||
| 3665 | case ZigTypeIdAnyFrame: | ||
| 3666 | zig_unreachable(); | ||
| 3667 | } | ||
| 3668 | zig_unreachable(); | ||
| 3669 | } | ||
| 3670 | |||
| 3671 | ZigType *get_src_ptr_type(ZigType *type) { | 3879 | ZigType *get_src_ptr_type(ZigType *type) { |
| 3672 | if (type->id == ZigTypeIdPointer) return type; | 3880 | if (type->id == ZigTypeIdPointer) return type; |
| 3673 | if (type->id == ZigTypeIdFn) return type; | 3881 | if (type->id == ZigTypeIdFn) return type; |
| ... | @@ -3803,6 +4011,13 @@ static void resolve_async_fn_frame(CodeGen *g, ZigFn *fn) { | ... | @@ -3803,6 +4011,13 @@ static void resolve_async_fn_frame(CodeGen *g, ZigFn *fn) { |
| 3803 | ZigType *frame_type = get_fn_frame_type(g, fn); | 4011 | ZigType *frame_type = get_fn_frame_type(g, fn); |
| 3804 | Error err; | 4012 | Error err; |
| 3805 | if ((err = type_resolve(g, frame_type, ResolveStatusSizeKnown))) { | 4013 | if ((err = type_resolve(g, frame_type, ResolveStatusSizeKnown))) { |
| 4014 | if (g->trace_err != nullptr && frame_type->data.frame.resolve_loop_src_node != nullptr && | ||
| 4015 | !frame_type->data.frame.reported_loop_err) | ||
| 4016 | { | ||
| 4017 | frame_type->data.frame.reported_loop_err = true; | ||
| 4018 | g->trace_err = add_error_note(g, g->trace_err, frame_type->data.frame.resolve_loop_src_node, | ||
| 4019 | buf_sprintf("when analyzing type '%s' here", buf_ptr(&frame_type->name))); | ||
| 4020 | } | ||
| 3806 | fn->anal_state = FnAnalStateInvalid; | 4021 | fn->anal_state = FnAnalStateInvalid; |
| 3807 | return; | 4022 | return; |
| 3808 | } | 4023 | } |
| ... | @@ -3918,7 +4133,7 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) { | ... | @@ -3918,7 +4133,7 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) { |
| 3918 | &fn->analyzed_executable, fn_type_id->return_type, return_type_node); | 4133 | &fn->analyzed_executable, fn_type_id->return_type, return_type_node); |
| 3919 | fn->src_implicit_return_type = block_return_type; | 4134 | fn->src_implicit_return_type = block_return_type; |
| 3920 | 4135 | ||
| 3921 | if (type_is_invalid(block_return_type) || fn->analyzed_executable.invalid) { | 4136 | if (type_is_invalid(block_return_type) || fn->analyzed_executable.first_err_trace_msg != nullptr) { |
| 3922 | assert(g->errors.length > 0); | 4137 | assert(g->errors.length > 0); |
| 3923 | fn->anal_state = FnAnalStateInvalid; | 4138 | fn->anal_state = FnAnalStateInvalid; |
| 3924 | return; | 4139 | return; |
| ... | @@ -4002,7 +4217,7 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) { | ... | @@ -4002,7 +4217,7 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) { |
| 4002 | assert(!fn_type->data.fn.is_generic); | 4217 | assert(!fn_type->data.fn.is_generic); |
| 4003 | 4218 | ||
| 4004 | ir_gen_fn(g, fn_table_entry); | 4219 | ir_gen_fn(g, fn_table_entry); |
| 4005 | if (fn_table_entry->ir_executable.invalid) { | 4220 | if (fn_table_entry->ir_executable.first_err_trace_msg != nullptr) { |
| 4006 | fn_table_entry->anal_state = FnAnalStateInvalid; | 4221 | fn_table_entry->anal_state = FnAnalStateInvalid; |
| 4007 | return; | 4222 | return; |
| 4008 | } | 4223 | } |
| ... | @@ -4140,12 +4355,14 @@ void semantic_analyze(CodeGen *g) { | ... | @@ -4140,12 +4355,14 @@ void semantic_analyze(CodeGen *g) { |
| 4140 | { | 4355 | { |
| 4141 | for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) { | 4356 | for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) { |
| 4142 | Tld *tld = g->resolve_queue.at(g->resolve_queue_index); | 4357 | Tld *tld = g->resolve_queue.at(g->resolve_queue_index); |
| 4358 | g->trace_err = nullptr; | ||
| 4143 | AstNode *source_node = nullptr; | 4359 | AstNode *source_node = nullptr; |
| 4144 | resolve_top_level_decl(g, tld, source_node); | 4360 | resolve_top_level_decl(g, tld, source_node, false); |
| 4145 | } | 4361 | } |
| 4146 | 4362 | ||
| 4147 | for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) { | 4363 | for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) { |
| 4148 | ZigFn *fn_entry = g->fn_defs.at(g->fn_defs_index); | 4364 | ZigFn *fn_entry = g->fn_defs.at(g->fn_defs_index); |
| 4365 | g->trace_err = nullptr; | ||
| 4149 | analyze_fn_body(g, fn_entry); | 4366 | analyze_fn_body(g, fn_entry); |
| 4150 | } | 4367 | } |
| 4151 | } | 4368 | } |
| ... | @@ -4157,6 +4374,7 @@ void semantic_analyze(CodeGen *g) { | ... | @@ -4157,6 +4374,7 @@ void semantic_analyze(CodeGen *g) { |
| 4157 | // second pass over functions for detecting async | 4374 | // second pass over functions for detecting async |
| 4158 | for (g->fn_defs_index = 0; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) { | 4375 | for (g->fn_defs_index = 0; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) { |
| 4159 | ZigFn *fn = g->fn_defs.at(g->fn_defs_index); | 4376 | ZigFn *fn = g->fn_defs.at(g->fn_defs_index); |
| 4377 | g->trace_err = nullptr; | ||
| 4160 | analyze_fn_async(g, fn, true); | 4378 | analyze_fn_async(g, fn, true); |
| 4161 | if (fn_is_async(fn) && fn->non_async_node != nullptr) { | 4379 | if (fn_is_async(fn) && fn->non_async_node != nullptr) { |
| 4162 | ErrorMsg *msg = add_node_error(g, fn->proto_node, | 4380 | ErrorMsg *msg = add_node_error(g, fn->proto_node, |
| ... | @@ -4802,7 +5020,10 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { | ... | @@ -4802,7 +5020,10 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { |
| 4802 | case ZigTypeIdStruct: | 5020 | case ZigTypeIdStruct: |
| 4803 | for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { | 5021 | for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { |
| 4804 | TypeStructField *field = &type_entry->data.structure.fields[i]; | 5022 | TypeStructField *field = &type_entry->data.structure.fields[i]; |
| 4805 | switch (type_has_one_possible_value(g, field->type_entry)) { | 5023 | OnePossibleValue opv = (field->type_entry != nullptr) ? |
| 5024 | type_has_one_possible_value(g, field->type_entry) : | ||
| 5025 | type_val_resolve_has_one_possible_value(g, field->type_val); | ||
| 5026 | switch (opv) { | ||
| 4806 | case OnePossibleValueInvalid: | 5027 | case OnePossibleValueInvalid: |
| 4807 | return OnePossibleValueInvalid; | 5028 | return OnePossibleValueInvalid; |
| 4808 | case OnePossibleValueNo: | 5029 | case OnePossibleValueNo: |
| ... | @@ -4828,18 +5049,19 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { | ... | @@ -4828,18 +5049,19 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { |
| 4828 | case ZigTypeIdUnion: | 5049 | case ZigTypeIdUnion: |
| 4829 | if (type_entry->data.unionation.src_field_count > 1) | 5050 | if (type_entry->data.unionation.src_field_count > 1) |
| 4830 | return OnePossibleValueNo; | 5051 | return OnePossibleValueNo; |
| 4831 | return type_has_one_possible_value(g, type_entry->data.unionation.fields[0].type_entry); | 5052 | TypeUnionField *only_field = &type_entry->data.unionation.fields[0]; |
| 5053 | if (only_field->type_entry != nullptr) { | ||
| 5054 | return type_has_one_possible_value(g, only_field->type_entry); | ||
| 5055 | } | ||
| 5056 | return type_val_resolve_has_one_possible_value(g, only_field->type_val); | ||
| 4832 | } | 5057 | } |
| 4833 | zig_unreachable(); | 5058 | zig_unreachable(); |
| 4834 | } | 5059 | } |
| 4835 | 5060 | ||
| 4836 | ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) { | 5061 | ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) { |
| 4837 | Error err; | 5062 | Error err; |
| 4838 | if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown))) | 5063 | switch (ty->id) { |
| 4839 | return ReqCompTimeInvalid; | ||
| 4840 | switch (type_entry->id) { | ||
| 4841 | case ZigTypeIdInvalid: | 5064 | case ZigTypeIdInvalid: |
| 4842 | case ZigTypeIdOpaque: | ||
| 4843 | zig_unreachable(); | 5065 | zig_unreachable(); |
| 4844 | case ZigTypeIdComptimeFloat: | 5066 | case ZigTypeIdComptimeFloat: |
| 4845 | case ZigTypeIdComptimeInt: | 5067 | case ZigTypeIdComptimeInt: |
| ... | @@ -4851,23 +5073,36 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) { | ... | @@ -4851,23 +5073,36 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) { |
| 4851 | case ZigTypeIdArgTuple: | 5073 | case ZigTypeIdArgTuple: |
| 4852 | return ReqCompTimeYes; | 5074 | return ReqCompTimeYes; |
| 4853 | case ZigTypeIdArray: | 5075 | case ZigTypeIdArray: |
| 4854 | return type_requires_comptime(g, type_entry->data.array.child_type); | 5076 | return type_requires_comptime(g, ty->data.array.child_type); |
| 4855 | case ZigTypeIdStruct: | 5077 | case ZigTypeIdStruct: |
| 4856 | return type_entry->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo; | 5078 | if (ty->data.structure.resolve_loop_flag_zero_bits) { |
| 5079 | // Does a struct which contains a pointer field to itself require comptime? No. | ||
| 5080 | return ReqCompTimeNo; | ||
| 5081 | } | ||
| 5082 | if ((err = type_resolve(g, ty, ResolveStatusZeroBitsKnown))) | ||
| 5083 | return ReqCompTimeInvalid; | ||
| 5084 | return ty->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo; | ||
| 4857 | case ZigTypeIdUnion: | 5085 | case ZigTypeIdUnion: |
| 4858 | return type_entry->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo; | 5086 | if (ty->data.unionation.resolve_loop_flag_zero_bits) { |
| 5087 | // Does a union which contains a pointer field to itself require comptime? No. | ||
| 5088 | return ReqCompTimeNo; | ||
| 5089 | } | ||
| 5090 | if ((err = type_resolve(g, ty, ResolveStatusZeroBitsKnown))) | ||
| 5091 | return ReqCompTimeInvalid; | ||
| 5092 | return ty->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo; | ||
| 4859 | case ZigTypeIdOptional: | 5093 | case ZigTypeIdOptional: |
| 4860 | return type_requires_comptime(g, type_entry->data.maybe.child_type); | 5094 | return type_requires_comptime(g, ty->data.maybe.child_type); |
| 4861 | case ZigTypeIdErrorUnion: | 5095 | case ZigTypeIdErrorUnion: |
| 4862 | return type_requires_comptime(g, type_entry->data.error_union.payload_type); | 5096 | return type_requires_comptime(g, ty->data.error_union.payload_type); |
| 4863 | case ZigTypeIdPointer: | 5097 | case ZigTypeIdPointer: |
| 4864 | if (type_entry->data.pointer.child_type->id == ZigTypeIdOpaque) { | 5098 | if (ty->data.pointer.child_type->id == ZigTypeIdOpaque) { |
| 4865 | return ReqCompTimeNo; | 5099 | return ReqCompTimeNo; |
| 4866 | } else { | 5100 | } else { |
| 4867 | return type_requires_comptime(g, type_entry->data.pointer.child_type); | 5101 | return type_requires_comptime(g, ty->data.pointer.child_type); |
| 4868 | } | 5102 | } |
| 4869 | case ZigTypeIdFn: | 5103 | case ZigTypeIdFn: |
| 4870 | return type_entry->data.fn.is_generic ? ReqCompTimeYes : ReqCompTimeNo; | 5104 | return ty->data.fn.is_generic ? ReqCompTimeYes : ReqCompTimeNo; |
| 5105 | case ZigTypeIdOpaque: | ||
| 4871 | case ZigTypeIdEnum: | 5106 | case ZigTypeIdEnum: |
| 4872 | case ZigTypeIdErrorSet: | 5107 | case ZigTypeIdErrorSet: |
| 4873 | case ZigTypeIdBool: | 5108 | case ZigTypeIdBool: |
| ... | @@ -5155,34 +5390,6 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_ | ... | @@ -5155,34 +5390,6 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_ |
| 5155 | } | 5390 | } |
| 5156 | 5391 | ||
| 5157 | 5392 | ||
| 5158 | void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { | ||
| 5159 | Error err; | ||
| 5160 | ZigType *wanted_type = const_val->type; | ||
| 5161 | if (wanted_type->id == ZigTypeIdArray) { | ||
| 5162 | const_val->special = ConstValSpecialStatic; | ||
| 5163 | const_val->data.x_array.special = ConstArraySpecialUndef; | ||
| 5164 | } else if (wanted_type->id == ZigTypeIdStruct) { | ||
| 5165 | if ((err = ensure_complete_type(g, wanted_type))) { | ||
| 5166 | return; | ||
| 5167 | } | ||
| 5168 | |||
| 5169 | const_val->special = ConstValSpecialStatic; | ||
| 5170 | size_t field_count = wanted_type->data.structure.src_field_count; | ||
| 5171 | const_val->data.x_struct.fields = create_const_vals(field_count); | ||
| 5172 | for (size_t i = 0; i < field_count; i += 1) { | ||
| 5173 | ConstExprValue *field_val = &const_val->data.x_struct.fields[i]; | ||
| 5174 | field_val->type = wanted_type->data.structure.fields[i].type_entry; | ||
| 5175 | assert(field_val->type); | ||
| 5176 | init_const_undefined(g, field_val); | ||
| 5177 | field_val->parent.id = ConstParentIdStruct; | ||
| 5178 | field_val->parent.data.p_struct.struct_val = const_val; | ||
| 5179 | field_val->parent.data.p_struct.field_index = i; | ||
| 5180 | } | ||
| 5181 | } else { | ||
| 5182 | const_val->special = ConstValSpecialUndef; | ||
| 5183 | } | ||
| 5184 | } | ||
| 5185 | |||
| 5186 | ConstExprValue *create_const_vals(size_t count) { | 5393 | ConstExprValue *create_const_vals(size_t count) { |
| 5187 | ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(count); | 5394 | ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(count); |
| 5188 | ConstExprValue *vals = allocate<ConstExprValue>(count); | 5395 | ConstExprValue *vals = allocate<ConstExprValue>(count); |
| ... | @@ -5192,10 +5399,6 @@ ConstExprValue *create_const_vals(size_t count) { | ... | @@ -5192,10 +5399,6 @@ ConstExprValue *create_const_vals(size_t count) { |
| 5192 | return vals; | 5399 | return vals; |
| 5193 | } | 5400 | } |
| 5194 | 5401 | ||
| 5195 | Error ensure_complete_type(CodeGen *g, ZigType *type_entry) { | ||
| 5196 | return type_resolve(g, type_entry, ResolveStatusSizeKnown); | ||
| 5197 | } | ||
| 5198 | |||
| 5199 | static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) { | 5402 | static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) { |
| 5200 | if (orig_fn_type->data.fn.fn_type_id.cc == CallingConventionAsync) | 5403 | if (orig_fn_type->data.fn.fn_type_id.cc == CallingConventionAsync) |
| 5201 | return orig_fn_type; | 5404 | return orig_fn_type; |
| ... | @@ -5209,27 +5412,6 @@ static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) { | ... | @@ -5209,27 +5412,6 @@ static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) { |
| 5209 | return fn_type; | 5412 | return fn_type; |
| 5210 | } | 5413 | } |
| 5211 | 5414 | ||
| 5212 | static void emit_error_notes_for_type_loop(CodeGen *g, ErrorMsg *msg, ZigType *stop_type, | ||
| 5213 | ZigType *ty, AstNode *src_node) | ||
| 5214 | { | ||
| 5215 | ErrorMsg *note = add_error_note(g, msg, src_node, | ||
| 5216 | buf_sprintf("when analyzing type '%s' here", buf_ptr(&ty->name))); | ||
| 5217 | if (ty == stop_type) | ||
| 5218 | return; | ||
| 5219 | switch (ty->id) { | ||
| 5220 | case ZigTypeIdFnFrame: { | ||
| 5221 | ty->data.frame.reported_loop_err = true; | ||
| 5222 | ZigType *depending_type = ty->data.frame.resolve_loop_type; | ||
| 5223 | if (depending_type == nullptr) | ||
| 5224 | return; | ||
| 5225 | emit_error_notes_for_type_loop(g, note, stop_type, | ||
| 5226 | depending_type, ty->data.frame.resolve_loop_src_node); | ||
| 5227 | } | ||
| 5228 | default: | ||
| 5229 | return; | ||
| 5230 | } | ||
| 5231 | } | ||
| 5232 | |||
| 5233 | static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { | 5415 | static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { |
| 5234 | Error err; | 5416 | Error err; |
| 5235 | 5417 | ||
| ... | @@ -5241,14 +5423,8 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { | ... | @@ -5241,14 +5423,8 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { |
| 5241 | 5423 | ||
| 5242 | if (frame_type->data.frame.resolve_loop_type != nullptr) { | 5424 | if (frame_type->data.frame.resolve_loop_type != nullptr) { |
| 5243 | if (!frame_type->data.frame.reported_loop_err) { | 5425 | if (!frame_type->data.frame.reported_loop_err) { |
| 5244 | frame_type->data.frame.reported_loop_err = true; | 5426 | add_node_error(g, fn->proto_node, |
| 5245 | ErrorMsg *msg = add_node_error(g, fn->proto_node, | ||
| 5246 | buf_sprintf("'%s' depends on itself", buf_ptr(&frame_type->name))); | 5427 | buf_sprintf("'%s' depends on itself", buf_ptr(&frame_type->name))); |
| 5247 | emit_error_notes_for_type_loop(g, msg, | ||
| 5248 | frame_type, | ||
| 5249 | frame_type->data.frame.resolve_loop_type, | ||
| 5250 | frame_type->data.frame.resolve_loop_src_node); | ||
| 5251 | emit_error_notes_for_ref_stack(g, msg); | ||
| 5252 | } | 5428 | } |
| 5253 | return ErrorSemanticAnalyzeFail; | 5429 | return ErrorSemanticAnalyzeFail; |
| 5254 | } | 5430 | } |
| ... | @@ -5264,11 +5440,9 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { | ... | @@ -5264,11 +5440,9 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { |
| 5264 | return ErrorSemanticAnalyzeFail; | 5440 | return ErrorSemanticAnalyzeFail; |
| 5265 | break; | 5441 | break; |
| 5266 | case FnAnalStateProbing: { | 5442 | case FnAnalStateProbing: { |
| 5267 | ErrorMsg *msg = add_node_error(g, fn->proto_node, | 5443 | add_node_error(g, fn->proto_node, |
| 5268 | buf_sprintf("cannot resolve '%s': function not fully analyzed yet", | 5444 | buf_sprintf("cannot resolve '%s': function not fully analyzed yet", |
| 5269 | buf_ptr(&frame_type->name))); | 5445 | buf_ptr(&frame_type->name))); |
| 5270 | ir_add_analysis_trace(fn->ir_executable.analysis, msg, | ||
| 5271 | buf_sprintf("depends on its own frame here")); | ||
| 5272 | return ErrorSemanticAnalyzeFail; | 5446 | return ErrorSemanticAnalyzeFail; |
| 5273 | } | 5447 | } |
| 5274 | } | 5448 | } |
| ... | @@ -5339,10 +5513,8 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { | ... | @@ -5339,10 +5513,8 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { |
| 5339 | if (callee->anal_state == FnAnalStateProbing) { | 5513 | if (callee->anal_state == FnAnalStateProbing) { |
| 5340 | ErrorMsg *msg = add_node_error(g, fn->proto_node, | 5514 | ErrorMsg *msg = add_node_error(g, fn->proto_node, |
| 5341 | buf_sprintf("unable to determine async function frame of '%s'", buf_ptr(&fn->symbol_name))); | 5515 | buf_sprintf("unable to determine async function frame of '%s'", buf_ptr(&fn->symbol_name))); |
| 5342 | ErrorMsg *note = add_error_note(g, msg, call->base.source_node, | 5516 | g->trace_err = add_error_note(g, msg, call->base.source_node, |
| 5343 | buf_sprintf("analysis of function '%s' depends on the frame", buf_ptr(&callee->symbol_name))); | 5517 | buf_sprintf("analysis of function '%s' depends on the frame", buf_ptr(&callee->symbol_name))); |
| 5344 | ir_add_analysis_trace(callee->ir_executable.analysis, note, | ||
| 5345 | buf_sprintf("depends on the frame here")); | ||
| 5346 | return ErrorSemanticAnalyzeFail; | 5518 | return ErrorSemanticAnalyzeFail; |
| 5347 | } | 5519 | } |
| 5348 | 5520 | ||
| ... | @@ -5454,6 +5626,37 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { | ... | @@ -5454,6 +5626,37 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { |
| 5454 | return ErrorNone; | 5626 | return ErrorNone; |
| 5455 | } | 5627 | } |
| 5456 | 5628 | ||
| 5629 | static Error resolve_pointer_zero_bits(CodeGen *g, ZigType *ty) { | ||
| 5630 | Error err; | ||
| 5631 | |||
| 5632 | if (ty->abi_size != SIZE_MAX) | ||
| 5633 | return ErrorNone; | ||
| 5634 | |||
| 5635 | if (ty->data.pointer.resolve_loop_flag_zero_bits) { | ||
| 5636 | ty->abi_size = g->builtin_types.entry_usize->abi_size; | ||
| 5637 | ty->size_in_bits = g->builtin_types.entry_usize->size_in_bits; | ||
| 5638 | ty->abi_align = g->builtin_types.entry_usize->abi_align; | ||
| 5639 | return ErrorNone; | ||
| 5640 | } | ||
| 5641 | ty->data.pointer.resolve_loop_flag_zero_bits = true; | ||
| 5642 | |||
| 5643 | ZigType *elem_type = ty->data.pointer.child_type; | ||
| 5644 | |||
| 5645 | if ((err = type_resolve(g, elem_type, ResolveStatusZeroBitsKnown))) | ||
| 5646 | return err; | ||
| 5647 | |||
| 5648 | if (type_has_bits(elem_type)) { | ||
| 5649 | ty->abi_size = g->builtin_types.entry_usize->abi_size; | ||
| 5650 | ty->size_in_bits = g->builtin_types.entry_usize->size_in_bits; | ||
| 5651 | ty->abi_align = g->builtin_types.entry_usize->abi_align; | ||
| 5652 | } else { | ||
| 5653 | ty->abi_size = 0; | ||
| 5654 | ty->size_in_bits = 0; | ||
| 5655 | ty->abi_align = 0; | ||
| 5656 | } | ||
| 5657 | return ErrorNone; | ||
| 5658 | } | ||
| 5659 | |||
| 5457 | Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) { | 5660 | Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) { |
| 5458 | if (type_is_invalid(ty)) | 5661 | if (type_is_invalid(ty)) |
| 5459 | return ErrorSemanticAnalyzeFail; | 5662 | return ErrorSemanticAnalyzeFail; |
| ... | @@ -5463,36 +5666,48 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) { | ... | @@ -5463,36 +5666,48 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) { |
| 5463 | case ResolveStatusInvalid: | 5666 | case ResolveStatusInvalid: |
| 5464 | zig_unreachable(); | 5667 | zig_unreachable(); |
| 5465 | case ResolveStatusZeroBitsKnown: | 5668 | case ResolveStatusZeroBitsKnown: |
| 5466 | if (ty->id == ZigTypeIdStruct) { | 5669 | switch (ty->id) { |
| 5467 | return resolve_struct_zero_bits(g, ty); | 5670 | case ZigTypeIdStruct: |
| 5468 | } else if (ty->id == ZigTypeIdEnum) { | 5671 | return resolve_struct_zero_bits(g, ty); |
| 5469 | return resolve_enum_zero_bits(g, ty); | 5672 | case ZigTypeIdEnum: |
| 5470 | } else if (ty->id == ZigTypeIdUnion) { | 5673 | return resolve_enum_zero_bits(g, ty); |
| 5471 | return resolve_union_zero_bits(g, ty); | 5674 | case ZigTypeIdUnion: |
| 5675 | return resolve_union_zero_bits(g, ty); | ||
| 5676 | case ZigTypeIdPointer: | ||
| 5677 | return resolve_pointer_zero_bits(g, ty); | ||
| 5678 | default: | ||
| 5679 | return ErrorNone; | ||
| 5472 | } | 5680 | } |
| 5473 | return ErrorNone; | ||
| 5474 | case ResolveStatusAlignmentKnown: | 5681 | case ResolveStatusAlignmentKnown: |
| 5475 | if (ty->id == ZigTypeIdStruct) { | 5682 | switch (ty->id) { |
| 5476 | return resolve_struct_alignment(g, ty); | 5683 | case ZigTypeIdStruct: |
| 5477 | } else if (ty->id == ZigTypeIdEnum) { | 5684 | return resolve_struct_alignment(g, ty); |
| 5478 | return resolve_enum_zero_bits(g, ty); | 5685 | case ZigTypeIdEnum: |
| 5479 | } else if (ty->id == ZigTypeIdUnion) { | 5686 | return resolve_enum_zero_bits(g, ty); |
| 5480 | return resolve_union_alignment(g, ty); | 5687 | case ZigTypeIdUnion: |
| 5481 | } else if (ty->id == ZigTypeIdFnFrame) { | 5688 | return resolve_union_alignment(g, ty); |
| 5482 | return resolve_async_frame(g, ty); | 5689 | case ZigTypeIdFnFrame: |
| 5690 | return resolve_async_frame(g, ty); | ||
| 5691 | case ZigTypeIdPointer: | ||
| 5692 | return resolve_pointer_zero_bits(g, ty); | ||
| 5693 | default: | ||
| 5694 | return ErrorNone; | ||
| 5483 | } | 5695 | } |
| 5484 | return ErrorNone; | ||
| 5485 | case ResolveStatusSizeKnown: | 5696 | case ResolveStatusSizeKnown: |
| 5486 | if (ty->id == ZigTypeIdStruct) { | 5697 | switch (ty->id) { |
| 5487 | return resolve_struct_type(g, ty); | 5698 | case ZigTypeIdStruct: |
| 5488 | } else if (ty->id == ZigTypeIdEnum) { | 5699 | return resolve_struct_type(g, ty); |
| 5489 | return resolve_enum_zero_bits(g, ty); | 5700 | case ZigTypeIdEnum: |
| 5490 | } else if (ty->id == ZigTypeIdUnion) { | 5701 | return resolve_enum_zero_bits(g, ty); |
| 5491 | return resolve_union_type(g, ty); | 5702 | case ZigTypeIdUnion: |
| 5492 | } else if (ty->id == ZigTypeIdFnFrame) { | 5703 | return resolve_union_type(g, ty); |
| 5493 | return resolve_async_frame(g, ty); | 5704 | case ZigTypeIdFnFrame: |
| 5705 | return resolve_async_frame(g, ty); | ||
| 5706 | case ZigTypeIdPointer: | ||
| 5707 | return resolve_pointer_zero_bits(g, ty); | ||
| 5708 | default: | ||
| 5709 | return ErrorNone; | ||
| 5494 | } | 5710 | } |
| 5495 | return ErrorNone; | ||
| 5496 | case ResolveStatusLLVMFwdDecl: | 5711 | case ResolveStatusLLVMFwdDecl: |
| 5497 | case ResolveStatusLLVMFull: | 5712 | case ResolveStatusLLVMFull: |
| 5498 | resolve_llvm_types(g, ty, status); | 5713 | resolve_llvm_types(g, ty, status); |
| ... | @@ -5867,6 +6082,9 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { | ... | @@ -5867,6 +6082,9 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { |
| 5867 | case ConstValSpecialRuntime: | 6082 | case ConstValSpecialRuntime: |
| 5868 | buf_appendf(buf, "(runtime value)"); | 6083 | buf_appendf(buf, "(runtime value)"); |
| 5869 | return; | 6084 | return; |
| 6085 | case ConstValSpecialLazy: | ||
| 6086 | buf_appendf(buf, "(lazy value)"); | ||
| 6087 | return; | ||
| 5870 | case ConstValSpecialUndef: | 6088 | case ConstValSpecialUndef: |
| 5871 | buf_appendf(buf, "undefined"); | 6089 | buf_appendf(buf, "undefined"); |
| 5872 | return; | 6090 | return; |
| ... | @@ -6241,6 +6459,40 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { | ... | @@ -6241,6 +6459,40 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { |
| 6241 | zig_unreachable(); | 6459 | zig_unreachable(); |
| 6242 | } | 6460 | } |
| 6243 | 6461 | ||
| 6462 | static void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { | ||
| 6463 | Error err; | ||
| 6464 | ZigType *wanted_type = const_val->type; | ||
| 6465 | if (wanted_type->id == ZigTypeIdArray) { | ||
| 6466 | const_val->special = ConstValSpecialStatic; | ||
| 6467 | const_val->data.x_array.special = ConstArraySpecialUndef; | ||
| 6468 | } else if (wanted_type->id == ZigTypeIdStruct) { | ||
| 6469 | if ((err = type_resolve(g, wanted_type, ResolveStatusZeroBitsKnown))) { | ||
| 6470 | return; | ||
| 6471 | } | ||
| 6472 | |||
| 6473 | const_val->special = ConstValSpecialStatic; | ||
| 6474 | size_t field_count = wanted_type->data.structure.src_field_count; | ||
| 6475 | const_val->data.x_struct.fields = create_const_vals(field_count); | ||
| 6476 | for (size_t i = 0; i < field_count; i += 1) { | ||
| 6477 | ConstExprValue *field_val = &const_val->data.x_struct.fields[i]; | ||
| 6478 | field_val->type = wanted_type->data.structure.fields[i].type_entry; | ||
| 6479 | assert(field_val->type); | ||
| 6480 | init_const_undefined(g, field_val); | ||
| 6481 | field_val->parent.id = ConstParentIdStruct; | ||
| 6482 | field_val->parent.data.p_struct.struct_val = const_val; | ||
| 6483 | field_val->parent.data.p_struct.field_index = i; | ||
| 6484 | } | ||
| 6485 | } else { | ||
| 6486 | const_val->special = ConstValSpecialUndef; | ||
| 6487 | } | ||
| 6488 | } | ||
| 6489 | |||
| 6490 | void expand_undef_struct(CodeGen *g, ConstExprValue *const_val) { | ||
| 6491 | if (const_val->special == ConstValSpecialUndef) { | ||
| 6492 | init_const_undefined(g, const_val); | ||
| 6493 | } | ||
| 6494 | } | ||
| 6495 | |||
| 6244 | // Canonicalize the array value as ConstArraySpecialNone | 6496 | // Canonicalize the array value as ConstArraySpecialNone |
| 6245 | void expand_undef_array(CodeGen *g, ConstExprValue *const_val) { | 6497 | void expand_undef_array(CodeGen *g, ConstExprValue *const_val) { |
| 6246 | size_t elem_count; | 6498 | size_t elem_count; |
| ... | @@ -6504,7 +6756,7 @@ bool type_ptr_eql(const ZigType *a, const ZigType *b) { | ... | @@ -6504,7 +6756,7 @@ bool type_ptr_eql(const ZigType *a, const ZigType *b) { |
| 6504 | 6756 | ||
| 6505 | ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) { | 6757 | ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) { |
| 6506 | Tld *tld = get_container_scope(codegen->compile_var_import)->decl_table.get(buf_create_from_str(name)); | 6758 | Tld *tld = get_container_scope(codegen->compile_var_import)->decl_table.get(buf_create_from_str(name)); |
| 6507 | resolve_top_level_decl(codegen, tld, nullptr); | 6759 | resolve_top_level_decl(codegen, tld, nullptr, false); |
| 6508 | assert(tld->id == TldIdVar); | 6760 | assert(tld->id == TldIdVar); |
| 6509 | TldVar *tld_var = (TldVar *)tld; | 6761 | TldVar *tld_var = (TldVar *)tld; |
| 6510 | ConstExprValue *var_value = tld_var->var->const_value; | 6762 | ConstExprValue *var_value = tld_var->var->const_value; |
| ... | @@ -6719,19 +6971,6 @@ bool ptr_allows_addr_zero(ZigType *ptr_type) { | ... | @@ -6719,19 +6971,6 @@ bool ptr_allows_addr_zero(ZigType *ptr_type) { |
| 6719 | return false; | 6971 | return false; |
| 6720 | } | 6972 | } |
| 6721 | 6973 | ||
| 6722 | void emit_error_notes_for_ref_stack(CodeGen *g, ErrorMsg *msg) { | ||
| 6723 | size_t i = g->tld_ref_source_node_stack.length; | ||
| 6724 | for (;;) { | ||
| 6725 | if (i == 0) | ||
| 6726 | break; | ||
| 6727 | i -= 1; | ||
| 6728 | AstNode *source_node = g->tld_ref_source_node_stack.at(i); | ||
| 6729 | if (source_node) { | ||
| 6730 | msg = add_error_note(g, msg, source_node, buf_sprintf("referenced here")); | ||
| 6731 | } | ||
| 6732 | } | ||
| 6733 | } | ||
| 6734 | |||
| 6735 | Buf *type_bare_name(ZigType *type_entry) { | 6974 | Buf *type_bare_name(ZigType *type_entry) { |
| 6736 | if (is_slice(type_entry)) { | 6975 | if (is_slice(type_entry)) { |
| 6737 | return &type_entry->name; | 6976 | return &type_entry->name; |
| ... | @@ -7134,10 +7373,9 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS | ... | @@ -7134,10 +7373,9 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS |
| 7134 | struct_type->data.structure.resolve_status = ResolveStatusLLVMFull; | 7373 | struct_type->data.structure.resolve_status = ResolveStatusLLVMFull; |
| 7135 | } | 7374 | } |
| 7136 | 7375 | ||
| 7137 | static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) { | 7376 | static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatus wanted_resolve_status) { |
| 7138 | assert(!enum_type->data.enumeration.is_invalid); | 7377 | assert(enum_type->data.enumeration.resolve_status >= ResolveStatusSizeKnown); |
| 7139 | assert(enum_type->data.enumeration.complete); | 7378 | if (enum_type->data.enumeration.resolve_status >= wanted_resolve_status) return; |
| 7140 | if (enum_type->llvm_di_type != nullptr) return; | ||
| 7141 | 7379 | ||
| 7142 | Scope *scope = &enum_type->data.enumeration.decls_scope->base; | 7380 | Scope *scope = &enum_type->data.enumeration.decls_scope->base; |
| 7143 | ZigType *import = get_scope_import(scope); | 7381 | ZigType *import = get_scope_import(scope); |
| ... | @@ -7158,6 +7396,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) { | ... | @@ -7158,6 +7396,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) { |
| 7158 | debug_align_in_bits, | 7396 | debug_align_in_bits, |
| 7159 | ZigLLVM_DIFlags_Zero, | 7397 | ZigLLVM_DIFlags_Zero, |
| 7160 | nullptr, di_element_types, (int)debug_field_count, 0, nullptr, ""); | 7398 | nullptr, di_element_types, (int)debug_field_count, 0, nullptr, ""); |
| 7399 | enum_type->data.enumeration.resolve_status = ResolveStatusLLVMFull; | ||
| 7161 | return; | 7400 | return; |
| 7162 | } | 7401 | } |
| 7163 | 7402 | ||
| ... | @@ -7190,14 +7429,16 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) { | ... | @@ -7190,14 +7429,16 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) { |
| 7190 | get_llvm_di_type(g, tag_int_type), ""); | 7429 | get_llvm_di_type(g, tag_int_type), ""); |
| 7191 | 7430 | ||
| 7192 | enum_type->llvm_di_type = tag_di_type; | 7431 | enum_type->llvm_di_type = tag_di_type; |
| 7432 | enum_type->data.enumeration.resolve_status = ResolveStatusLLVMFull; | ||
| 7193 | } | 7433 | } |
| 7194 | 7434 | ||
| 7195 | static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveStatus wanted_resolve_status) { | 7435 | static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveStatus wanted_resolve_status) { |
| 7196 | if (union_type->data.unionation.resolve_status >= wanted_resolve_status) return; | 7436 | if (union_type->data.unionation.resolve_status >= wanted_resolve_status) return; |
| 7197 | 7437 | ||
| 7198 | ZigType *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member; | 7438 | TypeUnionField *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member; |
| 7199 | ZigType *tag_type = union_type->data.unionation.tag_type; | 7439 | ZigType *tag_type = union_type->data.unionation.tag_type; |
| 7200 | if (most_aligned_union_member == nullptr) { | 7440 | uint32_t gen_field_count = union_type->data.unionation.gen_field_count; |
| 7441 | if (gen_field_count == 0) { | ||
| 7201 | union_type->llvm_type = get_llvm_type(g, tag_type); | 7442 | union_type->llvm_type = get_llvm_type(g, tag_type); |
| 7202 | union_type->llvm_di_type = get_llvm_di_type(g, tag_type); | 7443 | union_type->llvm_di_type = get_llvm_di_type(g, tag_type); |
| 7203 | union_type->data.unionation.resolve_status = ResolveStatusLLVMFull; | 7444 | union_type->data.unionation.resolve_status = ResolveStatusLLVMFull; |
| ... | @@ -7221,7 +7462,6 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta | ... | @@ -7221,7 +7462,6 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta |
| 7221 | if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return; | 7462 | if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return; |
| 7222 | } | 7463 | } |
| 7223 | 7464 | ||
| 7224 | uint32_t gen_field_count = union_type->data.unionation.gen_field_count; | ||
| 7225 | ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count); | 7465 | ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count); |
| 7226 | uint32_t field_count = union_type->data.unionation.src_field_count; | 7466 | uint32_t field_count = union_type->data.unionation.src_field_count; |
| 7227 | for (uint32_t i = 0; i < field_count; i += 1) { | 7467 | for (uint32_t i = 0; i < field_count; i += 1) { |
| ... | @@ -7248,17 +7488,17 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta | ... | @@ -7248,17 +7488,17 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta |
| 7248 | if (tag_type == nullptr || !type_has_bits(tag_type)) { | 7488 | if (tag_type == nullptr || !type_has_bits(tag_type)) { |
| 7249 | assert(most_aligned_union_member != nullptr); | 7489 | assert(most_aligned_union_member != nullptr); |
| 7250 | 7490 | ||
| 7251 | size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->abi_size; | 7491 | size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->type_entry->abi_size; |
| 7252 | if (padding_bytes > 0) { | 7492 | if (padding_bytes > 0) { |
| 7253 | ZigType *u8_type = get_int_type(g, false, 8); | 7493 | ZigType *u8_type = get_int_type(g, false, 8); |
| 7254 | ZigType *padding_array = get_array_type(g, u8_type, padding_bytes); | 7494 | ZigType *padding_array = get_array_type(g, u8_type, padding_bytes); |
| 7255 | LLVMTypeRef union_element_types[] = { | 7495 | LLVMTypeRef union_element_types[] = { |
| 7256 | most_aligned_union_member->llvm_type, | 7496 | most_aligned_union_member->type_entry->llvm_type, |
| 7257 | get_llvm_type(g, padding_array), | 7497 | get_llvm_type(g, padding_array), |
| 7258 | }; | 7498 | }; |
| 7259 | LLVMStructSetBody(union_type->llvm_type, union_element_types, 2, false); | 7499 | LLVMStructSetBody(union_type->llvm_type, union_element_types, 2, false); |
| 7260 | } else { | 7500 | } else { |
| 7261 | LLVMStructSetBody(union_type->llvm_type, &most_aligned_union_member->llvm_type, 1, false); | 7501 | LLVMStructSetBody(union_type->llvm_type, &most_aligned_union_member->type_entry->llvm_type, 1, false); |
| 7262 | } | 7502 | } |
| 7263 | union_type->data.unionation.union_llvm_type = union_type->llvm_type; | 7503 | union_type->data.unionation.union_llvm_type = union_type->llvm_type; |
| 7264 | union_type->data.unionation.gen_tag_index = SIZE_MAX; | 7504 | union_type->data.unionation.gen_tag_index = SIZE_MAX; |
| ... | @@ -7269,7 +7509,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta | ... | @@ -7269,7 +7509,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta |
| 7269 | ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&union_type->name), | 7509 | ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&union_type->name), |
| 7270 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), | 7510 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), |
| 7271 | union_type->data.unionation.union_abi_size * 8, | 7511 | union_type->data.unionation.union_abi_size * 8, |
| 7272 | most_aligned_union_member->abi_align * 8, | 7512 | most_aligned_union_member->align * 8, |
| 7273 | ZigLLVM_DIFlags_Zero, union_inner_di_types, | 7513 | ZigLLVM_DIFlags_Zero, union_inner_di_types, |
| 7274 | gen_field_count, 0, ""); | 7514 | gen_field_count, 0, ""); |
| 7275 | 7515 | ||
| ... | @@ -7280,14 +7520,14 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta | ... | @@ -7280,14 +7520,14 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta |
| 7280 | } | 7520 | } |
| 7281 | 7521 | ||
| 7282 | LLVMTypeRef union_type_ref; | 7522 | LLVMTypeRef union_type_ref; |
| 7283 | size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->abi_size; | 7523 | size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->type_entry->abi_size; |
| 7284 | if (padding_bytes == 0) { | 7524 | if (padding_bytes == 0) { |
| 7285 | union_type_ref = get_llvm_type(g, most_aligned_union_member); | 7525 | union_type_ref = get_llvm_type(g, most_aligned_union_member->type_entry); |
| 7286 | } else { | 7526 | } else { |
| 7287 | ZigType *u8_type = get_int_type(g, false, 8); | 7527 | ZigType *u8_type = get_int_type(g, false, 8); |
| 7288 | ZigType *padding_array = get_array_type(g, u8_type, padding_bytes); | 7528 | ZigType *padding_array = get_array_type(g, u8_type, padding_bytes); |
| 7289 | LLVMTypeRef union_element_types[] = { | 7529 | LLVMTypeRef union_element_types[] = { |
| 7290 | get_llvm_type(g, most_aligned_union_member), | 7530 | get_llvm_type(g, most_aligned_union_member->type_entry), |
| 7291 | get_llvm_type(g, padding_array), | 7531 | get_llvm_type(g, padding_array), |
| 7292 | }; | 7532 | }; |
| 7293 | union_type_ref = LLVMStructType(union_element_types, 2, false); | 7533 | union_type_ref = LLVMStructType(union_element_types, 2, false); |
| ... | @@ -7303,7 +7543,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta | ... | @@ -7303,7 +7543,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta |
| 7303 | ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, | 7543 | ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, |
| 7304 | ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion", | 7544 | ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion", |
| 7305 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), | 7545 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), |
| 7306 | most_aligned_union_member->size_in_bits, 8*most_aligned_union_member->abi_align, | 7546 | most_aligned_union_member->type_entry->size_in_bits, 8*most_aligned_union_member->align, |
| 7307 | ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, ""); | 7547 | ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, ""); |
| 7308 | 7548 | ||
| 7309 | uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->llvm_type, | 7549 | uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->llvm_type, |
| ... | @@ -7314,8 +7554,8 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta | ... | @@ -7314,8 +7554,8 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta |
| 7314 | ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, | 7554 | ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, |
| 7315 | ZigLLVMTypeToScope(union_type->llvm_di_type), "payload", | 7555 | ZigLLVMTypeToScope(union_type->llvm_di_type), "payload", |
| 7316 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), | 7556 | import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), |
| 7317 | most_aligned_union_member->size_in_bits, | 7557 | most_aligned_union_member->type_entry->size_in_bits, |
| 7318 | 8*most_aligned_union_member->abi_align, | 7558 | 8*most_aligned_union_member->align, |
| 7319 | union_offset_in_bits, | 7559 | union_offset_in_bits, |
| 7320 | ZigLLVM_DIFlags_Zero, union_di_type); | 7560 | ZigLLVM_DIFlags_Zero, union_di_type); |
| 7321 | 7561 | ||
| ... | @@ -7352,6 +7592,9 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta | ... | @@ -7352,6 +7592,9 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta |
| 7352 | static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) { | 7592 | static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) { |
| 7353 | if (type->llvm_di_type != nullptr) return; | 7593 | if (type->llvm_di_type != nullptr) return; |
| 7354 | 7594 | ||
| 7595 | if (resolve_pointer_zero_bits(g, type) != ErrorNone) | ||
| 7596 | zig_unreachable(); | ||
| 7597 | |||
| 7355 | if (!type_has_bits(type)) { | 7598 | if (!type_has_bits(type)) { |
| 7356 | type->llvm_type = g->builtin_types.entry_void->llvm_type; | 7599 | type->llvm_type = g->builtin_types.entry_void->llvm_type; |
| 7357 | type->llvm_di_type = g->builtin_types.entry_void->llvm_di_type; | 7600 | type->llvm_di_type = g->builtin_types.entry_void->llvm_di_type; |
| ... | @@ -7921,7 +8164,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r | ... | @@ -7921,7 +8164,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r |
| 7921 | else | 8164 | else |
| 7922 | return resolve_llvm_types_struct(g, type, wanted_resolve_status, nullptr); | 8165 | return resolve_llvm_types_struct(g, type, wanted_resolve_status, nullptr); |
| 7923 | case ZigTypeIdEnum: | 8166 | case ZigTypeIdEnum: |
| 7924 | return resolve_llvm_types_enum(g, type); | 8167 | return resolve_llvm_types_enum(g, type, wanted_resolve_status); |
| 7925 | case ZigTypeIdUnion: | 8168 | case ZigTypeIdUnion: |
| 7926 | return resolve_llvm_types_union(g, type, wanted_resolve_status); | 8169 | return resolve_llvm_types_union(g, type, wanted_resolve_status); |
| 7927 | case ZigTypeIdPointer: | 8170 | case ZigTypeIdPointer: |
src/analyze.hpp+8-8| ... | @@ -11,10 +11,9 @@ | ... | @@ -11,10 +11,9 @@ |
| 11 | #include "all_types.hpp" | 11 | #include "all_types.hpp" |
| 12 | 12 | ||
| 13 | void semantic_analyze(CodeGen *g); | 13 | void semantic_analyze(CodeGen *g); |
| 14 | ErrorMsg *add_node_error(CodeGen *g, const AstNode *node, Buf *msg); | 14 | ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg); |
| 15 | ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg); | 15 | ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg); |
| 16 | ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg); | 16 | ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg); |
| 17 | void emit_error_notes_for_ref_stack(CodeGen *g, ErrorMsg *msg); | ||
| 18 | ZigType *new_type_table_entry(ZigTypeId id); | 17 | ZigType *new_type_table_entry(ZigTypeId id); |
| 19 | ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn); | 18 | ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn); |
| 20 | ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const); | 19 | ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const); |
| ... | @@ -59,7 +58,7 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *abs_full_path, Bu | ... | @@ -59,7 +58,7 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *abs_full_path, Bu |
| 59 | ZigVar *find_variable(CodeGen *g, Scope *orig_context, Buf *name, ScopeFnDef **crossed_fndef_scope); | 58 | ZigVar *find_variable(CodeGen *g, Scope *orig_context, Buf *name, ScopeFnDef **crossed_fndef_scope); |
| 60 | Tld *find_decl(CodeGen *g, Scope *scope, Buf *name); | 59 | Tld *find_decl(CodeGen *g, Scope *scope, Buf *name); |
| 61 | Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name); | 60 | Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name); |
| 62 | void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node); | 61 | void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool allow_lazy); |
| 63 | 62 | ||
| 64 | ZigType *get_src_ptr_type(ZigType *type); | 63 | ZigType *get_src_ptr_type(ZigType *type); |
| 65 | ZigType *get_codegen_ptr_type(ZigType *type); | 64 | ZigType *get_codegen_ptr_type(ZigType *type); |
| ... | @@ -71,7 +70,6 @@ bool type_is_complete(ZigType *type_entry); | ... | @@ -71,7 +70,6 @@ bool type_is_complete(ZigType *type_entry); |
| 71 | bool type_is_resolved(ZigType *type_entry, ResolveStatus status); | 70 | bool type_is_resolved(ZigType *type_entry, ResolveStatus status); |
| 72 | bool type_is_invalid(ZigType *type_entry); | 71 | bool type_is_invalid(ZigType *type_entry); |
| 73 | bool type_is_global_error_set(ZigType *err_set_type); | 72 | bool type_is_global_error_set(ZigType *err_set_type); |
| 74 | Error resolve_container_type(CodeGen *g, ZigType *type_entry); | ||
| 75 | ScopeDecls *get_container_scope(ZigType *type_entry); | 73 | ScopeDecls *get_container_scope(ZigType *type_entry); |
| 76 | TypeStructField *find_struct_type_field(ZigType *type_entry, Buf *name); | 74 | TypeStructField *find_struct_type_field(ZigType *type_entry, Buf *name); |
| 77 | TypeEnumField *find_enum_type_field(ZigType *enum_type, Buf *name); | 75 | TypeEnumField *find_enum_type_field(ZigType *enum_type, Buf *name); |
| ... | @@ -95,7 +93,6 @@ ZigFn *create_fn(CodeGen *g, AstNode *proto_node); | ... | @@ -95,7 +93,6 @@ ZigFn *create_fn(CodeGen *g, AstNode *proto_node); |
| 95 | ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value); | 93 | ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value); |
| 96 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc); | 94 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc); |
| 97 | AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index); | 95 | AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index); |
| 98 | Error ATTRIBUTE_MUST_USE ensure_complete_type(CodeGen *g, ZigType *type_entry); | ||
| 99 | Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status); | 96 | Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status); |
| 100 | void complete_enum(CodeGen *g, ZigType *enum_type); | 97 | void complete_enum(CodeGen *g, ZigType *enum_type); |
| 101 | bool ir_get_var_is_comptime(ZigVar *var); | 98 | bool ir_get_var_is_comptime(ZigVar *var); |
| ... | @@ -169,12 +166,11 @@ ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t | ... | @@ -169,12 +166,11 @@ ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t |
| 169 | void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end); | 166 | void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end); |
| 170 | ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end); | 167 | ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end); |
| 171 | 168 | ||
| 172 | void init_const_undefined(CodeGen *g, ConstExprValue *const_val); | ||
| 173 | |||
| 174 | ConstExprValue *create_const_vals(size_t count); | 169 | ConstExprValue *create_const_vals(size_t count); |
| 175 | 170 | ||
| 176 | ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits); | 171 | ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits); |
| 177 | void expand_undef_array(CodeGen *g, ConstExprValue *const_val); | 172 | void expand_undef_array(CodeGen *g, ConstExprValue *const_val); |
| 173 | void expand_undef_struct(CodeGen *g, ConstExprValue *const_val); | ||
| 178 | void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value); | 174 | void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value); |
| 179 | 175 | ||
| 180 | const char *type_id_name(ZigTypeId id); | 176 | const char *type_id_name(ZigTypeId id); |
| ... | @@ -244,9 +240,13 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa | ... | @@ -244,9 +240,13 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa |
| 244 | 240 | ||
| 245 | void src_assert(bool ok, AstNode *source_node); | 241 | void src_assert(bool ok, AstNode *source_node); |
| 246 | bool is_container(ZigType *type_entry); | 242 | bool is_container(ZigType *type_entry); |
| 247 | ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name); | 243 | ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, |
| 244 | Buf *type_name, UndefAllowed undef); | ||
| 248 | 245 | ||
| 249 | void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn); | 246 | void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn); |
| 250 | bool fn_is_async(ZigFn *fn); | 247 | bool fn_is_async(ZigFn *fn); |
| 251 | 248 | ||
| 249 | Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align); | ||
| 250 | ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field); | ||
| 251 | |||
| 252 | #endif | 252 | #endif |
src/codegen.cpp+9-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) { |
| 3386 | 3386 | ||
| 3387 | static bool value_is_all_undef(ConstExprValue *const_val) { | 3387 | static 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: |
| ... | @@ -3525,6 +3527,8 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir | ... | @@ -3525,6 +3527,8 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir |
| 3525 | } | 3527 | } |
| 3526 | 3528 | ||
| 3527 | static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) { | 3529 | static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) { |
| 3530 | if (instruction->base.value.special != ConstValSpecialRuntime) | ||
| 3531 | return ir_llvm_value(g, &instruction->base); | ||
| 3528 | ZigVar *var = instruction->var; | 3532 | ZigVar *var = instruction->var; |
| 3529 | if (type_has_bits(var->var_type)) { | 3533 | if (type_has_bits(var->var_type)) { |
| 3530 | assert(var->value_ref); | 3534 | assert(var->value_ref); |
| ... | @@ -6041,6 +6045,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un | ... | @@ -6041,6 +6045,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un |
| 6041 | 6045 | ||
| 6042 | static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ConstExprValue *const_val) { | 6046 | static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ConstExprValue *const_val) { |
| 6043 | switch (const_val->special) { | 6047 | switch (const_val->special) { |
| 6048 | case ConstValSpecialLazy: | ||
| 6044 | case ConstValSpecialRuntime: | 6049 | case ConstValSpecialRuntime: |
| 6045 | zig_unreachable(); | 6050 | zig_unreachable(); |
| 6046 | case ConstValSpecialUndef: | 6051 | case ConstValSpecialUndef: |
| ... | @@ -6300,6 +6305,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c | ... | @@ -6300,6 +6305,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c |
| 6300 | assert(type_has_bits(type_entry)); | 6305 | assert(type_has_bits(type_entry)); |
| 6301 | 6306 | ||
| 6302 | switch (const_val->special) { | 6307 | switch (const_val->special) { |
| 6308 | case ConstValSpecialLazy: | ||
| 6309 | zig_unreachable(); | ||
| 6303 | case ConstValSpecialRuntime: | 6310 | case ConstValSpecialRuntime: |
| 6304 | zig_unreachable(); | 6311 | zig_unreachable(); |
| 6305 | case ConstValSpecialUndef: | 6312 | case ConstValSpecialUndef: |
| ... | @@ -6563,7 +6570,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c | ... | @@ -6563,7 +6570,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c |
| 6563 | uint64_t pad_bytes = type_entry->data.unionation.union_abi_size - field_type_bytes; | 6570 | uint64_t pad_bytes = type_entry->data.unionation.union_abi_size - field_type_bytes; |
| 6564 | LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value, ""); | 6571 | LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value, ""); |
| 6565 | make_unnamed_struct = is_llvm_value_unnamed_type(g, payload_value->type, correctly_typed_value) || | 6572 | make_unnamed_struct = is_llvm_value_unnamed_type(g, payload_value->type, correctly_typed_value) || |
| 6566 | payload_value->type != type_entry->data.unionation.most_aligned_union_member; | 6573 | payload_value->type != type_entry->data.unionation.most_aligned_union_member->type_entry; |
| 6567 | 6574 | ||
| 6568 | { | 6575 | { |
| 6569 | if (pad_bytes == 0) { | 6576 | if (pad_bytes == 0) { |
| ... | @@ -8891,7 +8898,7 @@ static void gen_root_source(CodeGen *g) { | ... | @@ -8891,7 +8898,7 @@ static void gen_root_source(CodeGen *g) { |
| 8891 | } | 8898 | } |
| 8892 | Tld *panic_tld = find_decl(g, &get_container_scope(import_with_panic)->base, buf_create_from_str("panic")); | 8899 | Tld *panic_tld = find_decl(g, &get_container_scope(import_with_panic)->base, buf_create_from_str("panic")); |
| 8893 | assert(panic_tld != nullptr); | 8900 | assert(panic_tld != nullptr); |
| 8894 | resolve_top_level_decl(g, panic_tld, nullptr); | 8901 | resolve_top_level_decl(g, panic_tld, nullptr, false); |
| 8895 | } | 8902 | } |
| 8896 | 8903 | ||
| 8897 | 8904 |
src/ir.cpp+858-508| ... | @@ -152,11 +152,6 @@ struct ConstCastBadAllowsZero { | ... | @@ -152,11 +152,6 @@ struct ConstCastBadAllowsZero { |
| 152 | }; | 152 | }; |
| 153 | 153 | ||
| 154 | 154 | ||
| 155 | enum UndefAllowed { | ||
| 156 | UndefOk, | ||
| 157 | UndefBad, | ||
| 158 | }; | ||
| 159 | |||
| 160 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); | 155 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| 161 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, | 156 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, |
| 162 | ResultLoc *result_loc); | 157 | ResultLoc *result_loc); |
| ... | @@ -234,6 +229,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c | ... | @@ -234,6 +229,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c |
| 234 | } | 229 | } |
| 235 | case ConstPtrSpecialBaseStruct: { | 230 | case ConstPtrSpecialBaseStruct: { |
| 236 | ConstExprValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val; | 231 | ConstExprValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val; |
| 232 | expand_undef_struct(g, struct_val); | ||
| 237 | result = &struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index]; | 233 | result = &struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index]; |
| 238 | break; | 234 | break; |
| 239 | } | 235 | } |
| ... | @@ -402,7 +398,7 @@ static void ir_ref_var(ZigVar *var) { | ... | @@ -402,7 +398,7 @@ static void ir_ref_var(ZigVar *var) { |
| 402 | ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) { | 398 | ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) { |
| 403 | ConstExprValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type, | 399 | ConstExprValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type, |
| 404 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr, | 400 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr, |
| 405 | node, nullptr, ira->new_irb.exec, nullptr); | 401 | node, nullptr, ira->new_irb.exec, nullptr, UndefBad); |
| 406 | 402 | ||
| 407 | if (type_is_invalid(result->type)) | 403 | if (type_is_invalid(result->type)) |
| 408 | return ira->codegen->builtin_types.entry_invalid; | 404 | return ira->codegen->builtin_types.entry_invalid; |
| ... | @@ -6858,7 +6854,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -6858,7 +6854,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod |
| 6858 | uint32_t len = asm_token.end - asm_token.start - 2; | 6854 | uint32_t len = asm_token.end - asm_token.start - 2; |
| 6859 | 6855 | ||
| 6860 | add_node_error(irb->codegen, node, | 6856 | add_node_error(irb->codegen, node, |
| 6861 | buf_sprintf("could not find '%.*s' in the inputs or outputs.", | 6857 | buf_sprintf("could not find '%.*s' in the inputs or outputs", |
| 6862 | len, ptr)); | 6858 | len, ptr)); |
| 6863 | return irb->codegen->invalid_instruction; | 6859 | return irb->codegen->invalid_instruction; |
| 6864 | } | 6860 | } |
| ... | @@ -8111,7 +8107,12 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc | ... | @@ -8111,7 +8107,12 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc |
| 8111 | ir_build_reset_result(irb, scope, node, result_loc); | 8107 | ir_build_reset_result(irb, scope, node, result_loc); |
| 8112 | } | 8108 | } |
| 8113 | IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc); | 8109 | IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc); |
| 8114 | irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); | 8110 | if (result == irb->codegen->invalid_instruction) { |
| 8111 | if (irb->exec->first_err_trace_msg == nullptr) { | ||
| 8112 | irb->exec->first_err_trace_msg = irb->codegen->trace_err; | ||
| 8113 | } | ||
| 8114 | src_assert(irb->exec->first_err_trace_msg != nullptr, node); | ||
| 8115 | } | ||
| 8115 | return result; | 8116 | return result; |
| 8116 | } | 8117 | } |
| 8117 | 8118 | ||
| ... | @@ -8119,21 +8120,20 @@ static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { | ... | @@ -8119,21 +8120,20 @@ static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { |
| 8119 | return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); | 8120 | return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| 8120 | } | 8121 | } |
| 8121 | 8122 | ||
| 8122 | static void invalidate_exec(IrExecutable *exec) { | 8123 | static void invalidate_exec(IrExecutable *exec, ErrorMsg *msg) { |
| 8123 | if (exec->invalid) | 8124 | if (exec->first_err_trace_msg != nullptr) |
| 8124 | return; | 8125 | return; |
| 8125 | 8126 | ||
| 8126 | exec->invalid = true; | 8127 | exec->first_err_trace_msg = msg; |
| 8127 | 8128 | ||
| 8128 | for (size_t i = 0; i < exec->tld_list.length; i += 1) { | 8129 | for (size_t i = 0; i < exec->tld_list.length; i += 1) { |
| 8129 | exec->tld_list.items[i]->resolution = TldResolutionInvalid; | 8130 | exec->tld_list.items[i]->resolution = TldResolutionInvalid; |
| 8130 | } | 8131 | } |
| 8131 | 8132 | ||
| 8132 | if (exec->source_exec != nullptr) | 8133 | if (exec->source_exec != nullptr) |
| 8133 | invalidate_exec(exec->source_exec); | 8134 | invalidate_exec(exec->source_exec, msg); |
| 8134 | } | 8135 | } |
| 8135 | 8136 | ||
| 8136 | |||
| 8137 | bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) { | 8137 | bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) { |
| 8138 | assert(node->owner); | 8138 | assert(node->owner); |
| 8139 | 8139 | ||
| ... | @@ -8151,8 +8151,10 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -8151,8 +8151,10 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8151 | 8151 | ||
| 8152 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); | 8152 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); |
| 8153 | assert(result); | 8153 | assert(result); |
| 8154 | if (irb->exec->invalid) | 8154 | if (irb->exec->first_err_trace_msg != nullptr) { |
| 8155 | codegen->trace_err = irb->exec->first_err_trace_msg; | ||
| 8155 | return false; | 8156 | return false; |
| 8157 | } | ||
| 8156 | 8158 | ||
| 8157 | if (!instr_is_unreachable(result)) { | 8159 | if (!instr_is_unreachable(result)) { |
| 8158 | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result)); | 8160 | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result)); |
| ... | @@ -8181,15 +8183,9 @@ static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, Error | ... | @@ -8181,15 +8183,9 @@ static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, Error |
| 8181 | ir_add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1); | 8183 | ir_add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1); |
| 8182 | } | 8184 | } |
| 8183 | 8185 | ||
| 8184 | void ir_add_analysis_trace(IrAnalyze *ira, ErrorMsg *err_msg, Buf *text) { | ||
| 8185 | IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); | ||
| 8186 | add_error_note(ira->codegen, err_msg, old_instruction->source_node, text); | ||
| 8187 | ir_add_call_stack_errors(ira->codegen, ira->new_irb.exec, err_msg, 10); | ||
| 8188 | } | ||
| 8189 | |||
| 8190 | static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) { | 8186 | static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) { |
| 8191 | invalidate_exec(exec); | ||
| 8192 | ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); | 8187 | ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); |
| 8188 | invalidate_exec(exec, err_msg); | ||
| 8193 | if (exec->parent_exec) { | 8189 | if (exec->parent_exec) { |
| 8194 | ir_add_call_stack_errors(codegen, exec, err_msg, 10); | 8190 | ir_add_call_stack_errors(codegen, exec, err_msg, 10); |
| 8195 | } | 8191 | } |
| ... | @@ -8223,6 +8219,7 @@ static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, Ast | ... | @@ -8223,6 +8219,7 @@ static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, Ast |
| 8223 | { | 8219 | { |
| 8224 | Error err; | 8220 | Error err; |
| 8225 | assert(ptr_val->type->id == ZigTypeIdPointer); | 8221 | assert(ptr_val->type->id == ZigTypeIdPointer); |
| 8222 | assert(ptr_val->special == ConstValSpecialStatic); | ||
| 8226 | ConstExprValue tmp = {}; | 8223 | ConstExprValue tmp = {}; |
| 8227 | tmp.special = ConstValSpecialStatic; | 8224 | tmp.special = ConstValSpecialStatic; |
| 8228 | tmp.type = ptr_val->type->data.pointer.child_type; | 8225 | tmp.type = ptr_val->type->data.pointer.child_type; |
| ... | @@ -9016,7 +9013,8 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -9016,7 +9013,8 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 9016 | } | 9013 | } |
| 9017 | 9014 | ||
| 9018 | ConstExprValue *const_val = ir_resolve_const(ira, instruction, UndefBad); | 9015 | ConstExprValue *const_val = ir_resolve_const(ira, instruction, UndefBad); |
| 9019 | assert(const_val != nullptr); | 9016 | if (const_val == nullptr) |
| 9017 | return false; | ||
| 9020 | 9018 | ||
| 9021 | bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt); | 9019 | bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt); |
| 9022 | bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat); | 9020 | bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat); |
| ... | @@ -9376,6 +9374,14 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted | ... | @@ -9376,6 +9374,14 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 9376 | result.id = ConstCastResultIdInvalid; | 9374 | result.id = ConstCastResultIdInvalid; |
| 9377 | return result; | 9375 | return result; |
| 9378 | } | 9376 | } |
| 9377 | if ((err = type_resolve(g, wanted_type, ResolveStatusZeroBitsKnown))) { | ||
| 9378 | result.id = ConstCastResultIdInvalid; | ||
| 9379 | return result; | ||
| 9380 | } | ||
| 9381 | if ((err = type_resolve(g, actual_type, ResolveStatusZeroBitsKnown))) { | ||
| 9382 | result.id = ConstCastResultIdInvalid; | ||
| 9383 | return result; | ||
| 9384 | } | ||
| 9379 | bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len; | 9385 | bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len; |
| 9380 | if ((ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr) && | 9386 | if ((ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr) && |
| 9381 | type_has_bits(wanted_type) == type_has_bits(actual_type) && | 9387 | type_has_bits(wanted_type) == type_has_bits(actual_type) && |
| ... | @@ -10634,7 +10640,7 @@ static void ir_finish_bb(IrAnalyze *ira) { | ... | @@ -10634,7 +10640,7 @@ static void ir_finish_bb(IrAnalyze *ira) { |
| 10634 | 10640 | ||
| 10635 | static IrInstruction *ir_unreach_error(IrAnalyze *ira) { | 10641 | static IrInstruction *ir_unreach_error(IrAnalyze *ira) { |
| 10636 | ira->old_bb_index = SIZE_MAX; | 10642 | ira->old_bb_index = SIZE_MAX; |
| 10637 | ira->new_irb.exec->invalid = true; | 10643 | assert(ira->new_irb.exec->first_err_trace_msg != nullptr); |
| 10638 | return ira->codegen->unreach_instruction; | 10644 | return ira->codegen->unreach_instruction; |
| 10639 | } | 10645 | } |
| 10640 | 10646 | ||
| ... | @@ -10722,32 +10728,57 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio | ... | @@ -10722,32 +10728,57 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio |
| 10722 | return const_instr; | 10728 | return const_instr; |
| 10723 | } | 10729 | } |
| 10724 | 10730 | ||
| 10731 | static Error ir_resolve_const_val(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, | ||
| 10732 | ConstExprValue *val, UndefAllowed undef_allowed) | ||
| 10733 | { | ||
| 10734 | Error err; | ||
| 10735 | for (;;) { | ||
| 10736 | switch (val->special) { | ||
| 10737 | case ConstValSpecialStatic: | ||
| 10738 | return ErrorNone; | ||
| 10739 | case ConstValSpecialRuntime: | ||
| 10740 | if (!type_has_bits(val->type)) | ||
| 10741 | return ErrorNone; | ||
| 10742 | |||
| 10743 | exec_add_error_node(codegen, exec, source_node, | ||
| 10744 | buf_sprintf("unable to evaluate constant expression")); | ||
| 10745 | return ErrorSemanticAnalyzeFail; | ||
| 10746 | case ConstValSpecialUndef: | ||
| 10747 | if (undef_allowed == UndefOk || undef_allowed == LazyOk) | ||
| 10748 | return ErrorNone; | ||
| 10749 | |||
| 10750 | exec_add_error_node(codegen, exec, source_node, | ||
| 10751 | buf_sprintf("use of undefined value here causes undefined behavior")); | ||
| 10752 | return ErrorSemanticAnalyzeFail; | ||
| 10753 | case ConstValSpecialLazy: | ||
| 10754 | if (undef_allowed == LazyOk || undef_allowed == LazyOkNoUndef) | ||
| 10755 | return ErrorNone; | ||
| 10756 | |||
| 10757 | if ((err = ir_resolve_lazy(codegen, source_node, val))) | ||
| 10758 | return err; | ||
| 10759 | |||
| 10760 | continue; | ||
| 10761 | } | ||
| 10762 | } | ||
| 10763 | } | ||
| 10764 | |||
| 10725 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { | 10765 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { |
| 10726 | switch (value->value.special) { | 10766 | Error err; |
| 10727 | case ConstValSpecialStatic: | 10767 | if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, value->source_node, |
| 10728 | return &value->value; | 10768 | &value->value, undef_allowed))) |
| 10729 | case ConstValSpecialRuntime: | 10769 | { |
| 10730 | if (!type_has_bits(value->value.type)) { | 10770 | return nullptr; |
| 10731 | return &value->value; | ||
| 10732 | } | ||
| 10733 | ir_add_error(ira, value, buf_sprintf("unable to evaluate constant expression")); | ||
| 10734 | return nullptr; | ||
| 10735 | case ConstValSpecialUndef: | ||
| 10736 | if (undef_allowed == UndefOk) { | ||
| 10737 | return &value->value; | ||
| 10738 | } else { | ||
| 10739 | ir_add_error(ira, value, buf_sprintf("use of undefined value here causes undefined behavior")); | ||
| 10740 | return nullptr; | ||
| 10741 | } | ||
| 10742 | } | 10771 | } |
| 10743 | zig_unreachable(); | 10772 | return &value->value; |
| 10744 | } | 10773 | } |
| 10745 | 10774 | ||
| 10746 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, | 10775 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, |
| 10747 | ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota, | 10776 | ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota, |
| 10748 | ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, | 10777 | ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, |
| 10749 | IrExecutable *parent_exec, AstNode *expected_type_source_node) | 10778 | IrExecutable *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef_allowed) |
| 10750 | { | 10779 | { |
| 10780 | Error err; | ||
| 10781 | |||
| 10751 | if (expected_type != nullptr && type_is_invalid(expected_type)) | 10782 | if (expected_type != nullptr && type_is_invalid(expected_type)) |
| 10752 | return &codegen->invalid_instruction->value; | 10783 | return &codegen->invalid_instruction->value; |
| 10753 | 10784 | ||
| ... | @@ -10761,8 +10792,10 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod | ... | @@ -10761,8 +10792,10 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod |
| 10761 | ir_executable->begin_scope = scope; | 10792 | ir_executable->begin_scope = scope; |
| 10762 | ir_gen(codegen, node, scope, ir_executable); | 10793 | ir_gen(codegen, node, scope, ir_executable); |
| 10763 | 10794 | ||
| 10764 | if (ir_executable->invalid) | 10795 | if (ir_executable->first_err_trace_msg != nullptr) { |
| 10796 | codegen->trace_err = ir_executable->first_err_trace_msg; | ||
| 10765 | return &codegen->invalid_instruction->value; | 10797 | return &codegen->invalid_instruction->value; |
| 10798 | } | ||
| 10766 | 10799 | ||
| 10767 | if (codegen->verbose_ir) { | 10800 | if (codegen->verbose_ir) { |
| 10768 | fprintf(stderr, "\nSource: "); | 10801 | fprintf(stderr, "\nSource: "); |
| ... | @@ -10783,8 +10816,9 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod | ... | @@ -10783,8 +10816,9 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod |
| 10783 | analyzed_executable->backward_branch_quota = backward_branch_quota; | 10816 | analyzed_executable->backward_branch_quota = backward_branch_quota; |
| 10784 | analyzed_executable->begin_scope = scope; | 10817 | analyzed_executable->begin_scope = scope; |
| 10785 | ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, expected_type_source_node); | 10818 | ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, expected_type_source_node); |
| 10786 | if (type_is_invalid(result_type)) | 10819 | if (type_is_invalid(result_type)) { |
| 10787 | return &codegen->invalid_instruction->value; | 10820 | return &codegen->invalid_instruction->value; |
| 10821 | } | ||
| 10788 | 10822 | ||
| 10789 | if (codegen->verbose_ir) { | 10823 | if (codegen->verbose_ir) { |
| 10790 | fprintf(stderr, "{ // (analyzed)\n"); | 10824 | fprintf(stderr, "{ // (analyzed)\n"); |
| ... | @@ -10792,7 +10826,14 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod | ... | @@ -10792,7 +10826,14 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod |
| 10792 | fprintf(stderr, "}\n"); | 10826 | fprintf(stderr, "}\n"); |
| 10793 | } | 10827 | } |
| 10794 | 10828 | ||
| 10795 | return ir_exec_const_result(codegen, analyzed_executable); | 10829 | ConstExprValue *result = ir_exec_const_result(codegen, analyzed_executable); |
| 10830 | if (type_is_invalid(result->type)) | ||
| 10831 | return &codegen->invalid_instruction->value; | ||
| 10832 | |||
| 10833 | if ((err = ir_resolve_const_val(codegen, analyzed_executable, node, result, undef_allowed))) | ||
| 10834 | return &codegen->invalid_instruction->value; | ||
| 10835 | |||
| 10836 | return result; | ||
| 10796 | } | 10837 | } |
| 10797 | 10838 | ||
| 10798 | static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_value) { | 10839 | static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_value) { |
| ... | @@ -10813,22 +10854,43 @@ static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_valu | ... | @@ -10813,22 +10854,43 @@ static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_valu |
| 10813 | return const_val->data.x_err_set; | 10854 | return const_val->data.x_err_set; |
| 10814 | } | 10855 | } |
| 10815 | 10856 | ||
| 10816 | static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { | 10857 | static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, |
| 10858 | ConstExprValue *val) | ||
| 10859 | { | ||
| 10860 | Error err; | ||
| 10861 | if ((err = ir_resolve_const_val(codegen, exec, source_node, val, UndefBad))) | ||
| 10862 | return codegen->builtin_types.entry_invalid; | ||
| 10863 | |||
| 10864 | assert(val->data.x_type != nullptr); | ||
| 10865 | return val->data.x_type; | ||
| 10866 | } | ||
| 10867 | |||
| 10868 | static ConstExprValue *ir_resolve_type_lazy(IrAnalyze *ira, IrInstruction *type_value) { | ||
| 10817 | if (type_is_invalid(type_value->value.type)) | 10869 | if (type_is_invalid(type_value->value.type)) |
| 10818 | return ira->codegen->builtin_types.entry_invalid; | 10870 | return nullptr; |
| 10819 | 10871 | ||
| 10820 | if (type_value->value.type->id != ZigTypeIdMetaType) { | 10872 | if (type_value->value.type->id != ZigTypeIdMetaType) { |
| 10821 | ir_add_error(ira, type_value, | 10873 | ir_add_error(ira, type_value, |
| 10822 | buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value.type->name))); | 10874 | buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value.type->name))); |
| 10823 | return ira->codegen->builtin_types.entry_invalid; | 10875 | return nullptr; |
| 10824 | } | 10876 | } |
| 10825 | 10877 | ||
| 10826 | ConstExprValue *const_val = ir_resolve_const(ira, type_value, UndefBad); | 10878 | Error err; |
| 10827 | if (!const_val) | 10879 | if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, type_value->source_node, |
| 10880 | &type_value->value, LazyOk))) | ||
| 10881 | { | ||
| 10882 | return nullptr; | ||
| 10883 | } | ||
| 10884 | |||
| 10885 | return &type_value->value; | ||
| 10886 | } | ||
| 10887 | |||
| 10888 | static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { | ||
| 10889 | ConstExprValue *val = ir_resolve_type_lazy(ira, type_value); | ||
| 10890 | if (val == nullptr) | ||
| 10828 | return ira->codegen->builtin_types.entry_invalid; | 10891 | return ira->codegen->builtin_types.entry_invalid; |
| 10829 | 10892 | ||
| 10830 | assert(const_val->data.x_type != nullptr); | 10893 | return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, val); |
| 10831 | return const_val->data.x_type; | ||
| 10832 | } | 10894 | } |
| 10833 | 10895 | ||
| 10834 | static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) { | 10896 | static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) { |
| ... | @@ -11026,14 +11088,21 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou | ... | @@ -11026,14 +11088,21 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou |
| 11026 | } | 11088 | } |
| 11027 | 11089 | ||
| 11028 | static IrInstruction *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInstruction *source_instr, | 11090 | static IrInstruction *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInstruction *source_instr, |
| 11029 | IrInstruction *value, ZigType *wanted_type) | 11091 | IrInstruction *frame_ptr, ZigType *wanted_type) |
| 11030 | { | 11092 | { |
| 11031 | if (instr_is_comptime(value)) { | 11093 | if (instr_is_comptime(frame_ptr)) { |
| 11032 | zig_panic("TODO comptime frame pointer"); | 11094 | ConstExprValue *ptr_val = ir_resolve_const(ira, frame_ptr, UndefBad); |
| 11095 | if (ptr_val == nullptr) | ||
| 11096 | return ira->codegen->invalid_instruction; | ||
| 11097 | |||
| 11098 | ir_assert(ptr_val->type->id == ZigTypeIdPointer, source_instr); | ||
| 11099 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { | ||
| 11100 | zig_panic("TODO comptime frame pointer"); | ||
| 11101 | } | ||
| 11033 | } | 11102 | } |
| 11034 | 11103 | ||
| 11035 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, | 11104 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| 11036 | wanted_type, value, CastOpBitCast); | 11105 | wanted_type, frame_ptr, CastOpBitCast); |
| 11037 | result->value.type = wanted_type; | 11106 | result->value.type = wanted_type; |
| 11038 | return result; | 11107 | return result; |
| 11039 | } | 11108 | } |
| ... | @@ -11152,6 +11221,9 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi | ... | @@ -11152,6 +11221,9 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi |
| 11152 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, | 11221 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, |
| 11153 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); | 11222 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 11154 | 11223 | ||
| 11224 | if ((err = type_resolve(ira->codegen, ptr_type, ResolveStatusZeroBitsKnown))) | ||
| 11225 | return ira->codegen->invalid_instruction; | ||
| 11226 | |||
| 11155 | IrInstruction *result_loc; | 11227 | IrInstruction *result_loc; |
| 11156 | if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) { | 11228 | if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) { |
| 11157 | result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true, | 11229 | result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true, |
| ... | @@ -11322,7 +11394,7 @@ static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruc | ... | @@ -11322,7 +11394,7 @@ static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruc |
| 11322 | IrInstruction *target, ZigType *wanted_type) | 11394 | IrInstruction *target, ZigType *wanted_type) |
| 11323 | { | 11395 | { |
| 11324 | IrInstruction *result = ir_const(ira, source_instr, wanted_type); | 11396 | IrInstruction *result = ir_const(ira, source_instr, wanted_type); |
| 11325 | init_const_undefined(ira->codegen, &result->value); | 11397 | result->value.special = ConstValSpecialUndef; |
| 11326 | return result; | 11398 | return result; |
| 11327 | } | 11399 | } |
| 11328 | 11400 | ||
| ... | @@ -11345,10 +11417,13 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so | ... | @@ -11345,10 +11417,13 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so |
| 11345 | return ira->codegen->invalid_instruction; | 11417 | return ira->codegen->invalid_instruction; |
| 11346 | TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); | 11418 | TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); |
| 11347 | assert(union_field != nullptr); | 11419 | assert(union_field != nullptr); |
| 11348 | if ((err = type_resolve(ira->codegen, union_field->type_entry, ResolveStatusZeroBitsKnown))) | 11420 | ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); |
| 11421 | if (field_type == nullptr) | ||
| 11422 | return ira->codegen->invalid_instruction; | ||
| 11423 | if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) | ||
| 11349 | return ira->codegen->invalid_instruction; | 11424 | return ira->codegen->invalid_instruction; |
| 11350 | 11425 | ||
| 11351 | switch (type_has_one_possible_value(ira->codegen, union_field->type_entry)) { | 11426 | switch (type_has_one_possible_value(ira->codegen, field_type)) { |
| 11352 | case OnePossibleValueInvalid: | 11427 | case OnePossibleValueInvalid: |
| 11353 | return ira->codegen->invalid_instruction; | 11428 | return ira->codegen->invalid_instruction; |
| 11354 | case OnePossibleValueNo: { | 11429 | case OnePossibleValueNo: { |
| ... | @@ -11357,7 +11432,7 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so | ... | @@ -11357,7 +11432,7 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so |
| 11357 | ErrorMsg *msg = ir_add_error(ira, source_instr, | 11432 | ErrorMsg *msg = ir_add_error(ira, source_instr, |
| 11358 | buf_sprintf("cast to union '%s' must initialize '%s' field '%s'", | 11433 | buf_sprintf("cast to union '%s' must initialize '%s' field '%s'", |
| 11359 | buf_ptr(&wanted_type->name), | 11434 | buf_ptr(&wanted_type->name), |
| 11360 | buf_ptr(&union_field->type_entry->name), | 11435 | buf_ptr(&field_type->name), |
| 11361 | buf_ptr(union_field->name))); | 11436 | buf_ptr(union_field->name))); |
| 11362 | add_error_note(ira->codegen, msg, field_node, | 11437 | add_error_note(ira->codegen, msg, field_node, |
| 11363 | buf_sprintf("field '%s' declared here", buf_ptr(union_field->name))); | 11438 | buf_sprintf("field '%s' declared here", buf_ptr(union_field->name))); |
| ... | @@ -11373,7 +11448,7 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so | ... | @@ -11373,7 +11448,7 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so |
| 11373 | bigint_init_bigint(&result->value.data.x_union.tag, &val->data.x_enum_tag); | 11448 | bigint_init_bigint(&result->value.data.x_union.tag, &val->data.x_enum_tag); |
| 11374 | result->value.data.x_union.payload = create_const_vals(1); | 11449 | result->value.data.x_union.payload = create_const_vals(1); |
| 11375 | result->value.data.x_union.payload->special = ConstValSpecialStatic; | 11450 | result->value.data.x_union.payload->special = ConstValSpecialStatic; |
| 11376 | result->value.data.x_union.payload->type = union_field->type_entry; | 11451 | result->value.data.x_union.payload->type = field_type; |
| 11377 | return result; | 11452 | return result; |
| 11378 | } | 11453 | } |
| 11379 | 11454 | ||
| ... | @@ -11390,12 +11465,17 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so | ... | @@ -11390,12 +11465,17 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so |
| 11390 | buf_ptr(&wanted_type->name))); | 11465 | buf_ptr(&wanted_type->name))); |
| 11391 | for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) { | 11466 | for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) { |
| 11392 | TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; | 11467 | TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; |
| 11393 | if (type_has_bits(union_field->type_entry)) { | 11468 | ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); |
| 11469 | if (field_type == nullptr) | ||
| 11470 | return ira->codegen->invalid_instruction; | ||
| 11471 | if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) | ||
| 11472 | return ira->codegen->invalid_instruction; | ||
| 11473 | if (type_has_bits(field_type)) { | ||
| 11394 | AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); | 11474 | AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); |
| 11395 | add_error_note(ira->codegen, msg, field_node, | 11475 | add_error_note(ira->codegen, msg, field_node, |
| 11396 | buf_sprintf("field '%s' has type '%s'", | 11476 | buf_sprintf("field '%s' has type '%s'", |
| 11397 | buf_ptr(union_field->name), | 11477 | buf_ptr(union_field->name), |
| 11398 | buf_ptr(&union_field->type_entry->name))); | 11478 | buf_ptr(&field_type->name))); |
| 11399 | } | 11479 | } |
| 11400 | } | 11480 | } |
| 11401 | return ira->codegen->invalid_instruction; | 11481 | return ira->codegen->invalid_instruction; |
| ... | @@ -11461,7 +11541,7 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour | ... | @@ -11461,7 +11541,7 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour |
| 11461 | 11541 | ||
| 11462 | ZigType *actual_type = target->value.type; | 11542 | ZigType *actual_type = target->value.type; |
| 11463 | 11543 | ||
| 11464 | if ((err = ensure_complete_type(ira->codegen, wanted_type))) | 11544 | if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusSizeKnown))) |
| 11465 | return ira->codegen->invalid_instruction; | 11545 | return ira->codegen->invalid_instruction; |
| 11466 | 11546 | ||
| 11467 | if (actual_type != wanted_type->data.enumeration.tag_int_type) { | 11547 | if (actual_type != wanted_type->data.enumeration.tag_int_type) { |
| ... | @@ -12508,26 +12588,22 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc | ... | @@ -12508,26 +12588,22 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc |
| 12508 | return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); | 12588 | return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); |
| 12509 | } | 12589 | } |
| 12510 | 12590 | ||
| 12511 | static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { | 12591 | static bool ir_resolve_const_align(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, |
| 12512 | if (type_is_invalid(value->value.type)) | 12592 | ConstExprValue *const_val, uint32_t *out) |
| 12513 | return false; | 12593 | { |
| 12514 | 12594 | Error err; | |
| 12515 | IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); | 12595 | if ((err = ir_resolve_const_val(codegen, exec, source_node, const_val, UndefBad))) |
| 12516 | if (type_is_invalid(casted_value->value.type)) | ||
| 12517 | return false; | ||
| 12518 | |||
| 12519 | ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); | ||
| 12520 | if (!const_val) | ||
| 12521 | return false; | 12596 | return false; |
| 12522 | 12597 | ||
| 12523 | uint32_t align_bytes = bigint_as_u32(&const_val->data.x_bigint); | 12598 | uint32_t align_bytes = bigint_as_u32(&const_val->data.x_bigint); |
| 12524 | if (align_bytes == 0) { | 12599 | if (align_bytes == 0) { |
| 12525 | ir_add_error(ira, value, buf_sprintf("alignment must be >= 1")); | 12600 | exec_add_error_node(codegen, exec, source_node, buf_sprintf("alignment must be >= 1")); |
| 12526 | return false; | 12601 | return false; |
| 12527 | } | 12602 | } |
| 12528 | 12603 | ||
| 12529 | if (!is_power_of_2(align_bytes)) { | 12604 | if (!is_power_of_2(align_bytes)) { |
| 12530 | ir_add_error(ira, value, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); | 12605 | exec_add_error_node(codegen, exec, source_node, |
| 12606 | buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); | ||
| 12531 | return false; | 12607 | return false; |
| 12532 | } | 12608 | } |
| 12533 | 12609 | ||
| ... | @@ -12535,6 +12611,18 @@ static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out | ... | @@ -12535,6 +12611,18 @@ static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out |
| 12535 | return true; | 12611 | return true; |
| 12536 | } | 12612 | } |
| 12537 | 12613 | ||
| 12614 | static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { | ||
| 12615 | if (type_is_invalid(value->value.type)) | ||
| 12616 | return false; | ||
| 12617 | |||
| 12618 | IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); | ||
| 12619 | if (type_is_invalid(casted_value->value.type)) | ||
| 12620 | return false; | ||
| 12621 | |||
| 12622 | return ir_resolve_const_align(ira->codegen, ira->new_irb.exec, value->source_node, | ||
| 12623 | &casted_value->value, out); | ||
| 12624 | } | ||
| 12625 | |||
| 12538 | static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { | 12626 | static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { |
| 12539 | if (type_is_invalid(value->value.type)) | 12627 | if (type_is_invalid(value->value.type)) |
| 12540 | return false; | 12628 | return false; |
| ... | @@ -12719,7 +12807,9 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio | ... | @@ -12719,7 +12807,9 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio |
| 12719 | if (type_is_invalid(operand->value.type)) | 12807 | if (type_is_invalid(operand->value.type)) |
| 12720 | return ir_unreach_error(ira); | 12808 | return ir_unreach_error(ira); |
| 12721 | 12809 | ||
| 12722 | if (!instr_is_comptime(operand) && handle_is_ptr(ira->explicit_return_type)) { | 12810 | if (!instr_is_comptime(operand) && ira->explicit_return_type != nullptr && |
| 12811 | handle_is_ptr(ira->explicit_return_type)) | ||
| 12812 | { | ||
| 12723 | // result location mechanism took care of it. | 12813 | // result location mechanism took care of it. |
| 12724 | IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, | 12814 | IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, |
| 12725 | instruction->base.source_node, nullptr); | 12815 | instruction->base.source_node, nullptr); |
| ... | @@ -13576,21 +13666,34 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -13576,21 +13666,34 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 13576 | if (type_is_invalid(casted_op2->value.type)) | 13666 | if (type_is_invalid(casted_op2->value.type)) |
| 13577 | return ira->codegen->invalid_instruction; | 13667 | return ira->codegen->invalid_instruction; |
| 13578 | 13668 | ||
| 13579 | if (op1->value.special == ConstValSpecialUndef || casted_op2->value.special == ConstValSpecialUndef) { | 13669 | // If either operand is undef, result is undef. |
| 13580 | IrInstruction *result = ir_const(ira, &instruction->base, op1->value.type); | 13670 | ConstExprValue *op1_val = nullptr; |
| 13581 | result->value.special = ConstValSpecialUndef; | 13671 | ConstExprValue *op2_val = nullptr; |
| 13582 | return result; | 13672 | if (instr_is_comptime(op1)) { |
| 13673 | op1_val = ir_resolve_const(ira, op1, UndefOk); | ||
| 13674 | if (op1_val == nullptr) | ||
| 13675 | return ira->codegen->invalid_instruction; | ||
| 13676 | if (op1_val->special == ConstValSpecialUndef) | ||
| 13677 | return ir_const_undef(ira, &instruction->base, op1->value.type); | ||
| 13583 | } | 13678 | } |
| 13584 | if (casted_op2->value.special == ConstValSpecialStatic && op1->value.special == ConstValSpecialStatic && | 13679 | if (instr_is_comptime(casted_op2)) { |
| 13680 | op2_val = ir_resolve_const(ira, casted_op2, UndefOk); | ||
| 13681 | if (op2_val == nullptr) | ||
| 13682 | return ira->codegen->invalid_instruction; | ||
| 13683 | if (op2_val->special == ConstValSpecialUndef) | ||
| 13684 | return ir_const_undef(ira, &instruction->base, op1->value.type); | ||
| 13685 | } | ||
| 13686 | |||
| 13687 | if (op2_val != nullptr && op1_val != nullptr && | ||
| 13585 | (op1->value.data.x_ptr.special == ConstPtrSpecialHardCodedAddr || | 13688 | (op1->value.data.x_ptr.special == ConstPtrSpecialHardCodedAddr || |
| 13586 | op1->value.data.x_ptr.special == ConstPtrSpecialNull)) | 13689 | op1->value.data.x_ptr.special == ConstPtrSpecialNull)) |
| 13587 | { | 13690 | { |
| 13588 | uint64_t start_addr = (op1->value.data.x_ptr.special == ConstPtrSpecialNull) ? | 13691 | uint64_t start_addr = (op1_val->data.x_ptr.special == ConstPtrSpecialNull) ? |
| 13589 | 0 : op1->value.data.x_ptr.data.hard_coded_addr.addr; | 13692 | 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; |
| 13590 | uint64_t elem_offset; | 13693 | uint64_t elem_offset; |
| 13591 | if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) | 13694 | if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) |
| 13592 | return ira->codegen->invalid_instruction; | 13695 | return ira->codegen->invalid_instruction; |
| 13593 | ZigType *elem_type = op1->value.type->data.pointer.child_type; | 13696 | ZigType *elem_type = op1_val->type->data.pointer.child_type; |
| 13594 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) | 13697 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) |
| 13595 | return ira->codegen->invalid_instruction; | 13698 | return ira->codegen->invalid_instruction; |
| 13596 | uint64_t byte_offset = type_size(ira->codegen, elem_type) * elem_offset; | 13699 | uint64_t byte_offset = type_size(ira->codegen, elem_type) * elem_offset; |
| ... | @@ -13602,7 +13705,7 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -13602,7 +13705,7 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 13602 | } else { | 13705 | } else { |
| 13603 | zig_unreachable(); | 13706 | zig_unreachable(); |
| 13604 | } | 13707 | } |
| 13605 | IrInstruction *result = ir_const(ira, &instruction->base, op1->value.type); | 13708 | IrInstruction *result = ir_const(ira, &instruction->base, op1_val->type); |
| 13606 | result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; | 13709 | result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; |
| 13607 | result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar; | 13710 | result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar; |
| 13608 | result->value.data.x_ptr.data.hard_coded_addr.addr = new_addr; | 13711 | result->value.data.x_ptr.data.hard_coded_addr.addr = new_addr; |
| ... | @@ -14171,9 +14274,13 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -14171,9 +14274,13 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 14171 | } | 14274 | } |
| 14172 | break; | 14275 | break; |
| 14173 | case ReqCompTimeNo: | 14276 | case ReqCompTimeNo: |
| 14174 | if (init_val != nullptr) { | 14277 | if (init_val != nullptr && value_is_comptime(init_val)) { |
| 14175 | if (init_val->special == ConstValSpecialStatic && | 14278 | if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, |
| 14176 | init_val->type->id == ZigTypeIdFn && | 14279 | decl_var_instruction->base.source_node, init_val, UndefOk))) |
| 14280 | { | ||
| 14281 | result_type = ira->codegen->builtin_types.entry_invalid; | ||
| 14282 | } else if (init_val->type->id == ZigTypeIdFn && | ||
| 14283 | init_val->special != ConstValSpecialUndef && | ||
| 14177 | init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && | 14284 | init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && |
| 14178 | init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) | 14285 | init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) |
| 14179 | { | 14286 | { |
| ... | @@ -14231,7 +14338,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -14231,7 +14338,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 14231 | } | 14338 | } |
| 14232 | } | 14339 | } |
| 14233 | 14340 | ||
| 14234 | if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) { | 14341 | if (init_val != nullptr && value_is_comptime(init_val)) { |
| 14235 | // Resolve ConstPtrMutInfer | 14342 | // Resolve ConstPtrMutInfer |
| 14236 | if (var->gen_is_const) { | 14343 | if (var->gen_is_const) { |
| 14237 | var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeConst; | 14344 | var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| ... | @@ -14242,6 +14349,10 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -14242,6 +14349,10 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 14242 | // since it's a comptime val there are no instructions for it. | 14349 | // since it's a comptime val there are no instructions for it. |
| 14243 | // we memcpy the init value here | 14350 | // we memcpy the init value here |
| 14244 | IrInstruction *deref = ir_get_deref(ira, var_ptr, var_ptr, nullptr); | 14351 | IrInstruction *deref = ir_get_deref(ira, var_ptr, var_ptr, nullptr); |
| 14352 | if (type_is_invalid(deref->value.type)) { | ||
| 14353 | var->var_type = ira->codegen->builtin_types.entry_invalid; | ||
| 14354 | return ira->codegen->invalid_instruction; | ||
| 14355 | } | ||
| 14245 | // If this assertion trips, something is wrong with the IR instructions, because | 14356 | // If this assertion trips, something is wrong with the IR instructions, because |
| 14246 | // we expected the above deref to return a constant value, but it created a runtime | 14357 | // we expected the above deref to return a constant value, but it created a runtime |
| 14247 | // instruction. | 14358 | // instruction. |
| ... | @@ -14250,7 +14361,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -14250,7 +14361,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 14250 | ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref, false); | 14361 | ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref, false); |
| 14251 | } | 14362 | } |
| 14252 | 14363 | ||
| 14253 | if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) { | 14364 | if (instr_is_comptime(var_ptr) && var->mem_slot_index != SIZE_MAX) { |
| 14254 | assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); | 14365 | assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); |
| 14255 | ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); | 14366 | ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); |
| 14256 | copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); | 14367 | copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); |
| ... | @@ -14555,6 +14666,10 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in | ... | @@ -14555,6 +14666,10 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in |
| 14555 | 14666 | ||
| 14556 | if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown))) | 14667 | if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown))) |
| 14557 | return ira->codegen->invalid_instruction; | 14668 | return ira->codegen->invalid_instruction; |
| 14669 | if (align != 0) { | ||
| 14670 | if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown))) | ||
| 14671 | return ira->codegen->invalid_instruction; | ||
| 14672 | } | ||
| 14558 | assert(result->base.value.data.x_ptr.special != ConstPtrSpecialInvalid); | 14673 | assert(result->base.value.data.x_ptr.special != ConstPtrSpecialInvalid); |
| 14559 | 14674 | ||
| 14560 | pointee->type = var_type; | 14675 | pointee->type = var_type; |
| ... | @@ -15174,23 +15289,25 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | ... | @@ -15174,23 +15289,25 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 15174 | 15289 | ||
| 15175 | bool comptime_var_mem = ir_get_var_is_comptime(var); | 15290 | bool comptime_var_mem = ir_get_var_is_comptime(var); |
| 15176 | bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern; | 15291 | bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern; |
| 15177 | bool is_const = var->src_is_const; | ||
| 15178 | bool is_volatile = false; | 15292 | bool is_volatile = false; |
| 15179 | 15293 | ||
| 15294 | IrInstruction *result = ir_build_var_ptr(&ira->new_irb, | ||
| 15295 | instruction->scope, instruction->source_node, var); | ||
| 15296 | result->value.type = get_pointer_to_type_extra(ira->codegen, var->var_type, | ||
| 15297 | var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0, false); | ||
| 15298 | |||
| 15180 | if (linkage_makes_it_runtime) | 15299 | if (linkage_makes_it_runtime) |
| 15181 | goto no_mem_slot; | 15300 | goto no_mem_slot; |
| 15182 | 15301 | ||
| 15183 | if (var->const_value->special == ConstValSpecialStatic) { | 15302 | if (value_is_comptime(var->const_value)) { |
| 15184 | mem_slot = var->const_value; | 15303 | mem_slot = var->const_value; |
| 15185 | } else { | 15304 | } else if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { |
| 15186 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { | 15305 | // find the relevant exec_context |
| 15187 | // find the relevant exec_context | 15306 | assert(var->owner_exec != nullptr); |
| 15188 | assert(var->owner_exec != nullptr); | 15307 | assert(var->owner_exec->analysis != nullptr); |
| 15189 | assert(var->owner_exec->analysis != nullptr); | 15308 | IrExecContext *exec_context = &var->owner_exec->analysis->exec_context; |
| 15190 | IrExecContext *exec_context = &var->owner_exec->analysis->exec_context; | 15309 | assert(var->mem_slot_index < exec_context->mem_slot_list.length); |
| 15191 | assert(var->mem_slot_index < exec_context->mem_slot_list.length); | 15310 | mem_slot = exec_context->mem_slot_list.at(var->mem_slot_index); |
| 15192 | mem_slot = exec_context->mem_slot_list.at(var->mem_slot_index); | ||
| 15193 | } | ||
| 15194 | } | 15311 | } |
| 15195 | 15312 | ||
| 15196 | if (mem_slot != nullptr) { | 15313 | if (mem_slot != nullptr) { |
| ... | @@ -15198,6 +15315,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | ... | @@ -15198,6 +15315,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 15198 | case ConstValSpecialRuntime: | 15315 | case ConstValSpecialRuntime: |
| 15199 | goto no_mem_slot; | 15316 | goto no_mem_slot; |
| 15200 | case ConstValSpecialStatic: // fallthrough | 15317 | case ConstValSpecialStatic: // fallthrough |
| 15318 | case ConstValSpecialLazy: // fallthrough | ||
| 15201 | case ConstValSpecialUndef: { | 15319 | case ConstValSpecialUndef: { |
| 15202 | ConstPtrMut ptr_mut; | 15320 | ConstPtrMut ptr_mut; |
| 15203 | if (comptime_var_mem) { | 15321 | if (comptime_var_mem) { |
| ... | @@ -15208,8 +15326,11 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | ... | @@ -15208,8 +15326,11 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 15208 | assert(!comptime_var_mem); | 15326 | assert(!comptime_var_mem); |
| 15209 | ptr_mut = ConstPtrMutRuntimeVar; | 15327 | ptr_mut = ConstPtrMutRuntimeVar; |
| 15210 | } | 15328 | } |
| 15211 | return ir_get_const_ptr(ira, instruction, mem_slot, var->var_type, | 15329 | result->value.special = ConstValSpecialStatic; |
| 15212 | ptr_mut, is_const, is_volatile, var->align_bytes); | 15330 | result->value.data.x_ptr.mut = ptr_mut; |
| 15331 | result->value.data.x_ptr.special = ConstPtrSpecialRef; | ||
| 15332 | result->value.data.x_ptr.data.ref.pointee = mem_slot; | ||
| 15333 | return result; | ||
| 15213 | } | 15334 | } |
| 15214 | } | 15335 | } |
| 15215 | zig_unreachable(); | 15336 | zig_unreachable(); |
| ... | @@ -15217,15 +15338,10 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | ... | @@ -15217,15 +15338,10 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 15217 | 15338 | ||
| 15218 | no_mem_slot: | 15339 | no_mem_slot: |
| 15219 | 15340 | ||
| 15220 | IrInstruction *var_ptr_instruction = ir_build_var_ptr(&ira->new_irb, | ||
| 15221 | instruction->scope, instruction->source_node, var); | ||
| 15222 | var_ptr_instruction->value.type = get_pointer_to_type_extra(ira->codegen, var->var_type, | ||
| 15223 | var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0, false); | ||
| 15224 | |||
| 15225 | bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr); | 15341 | bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr); |
| 15226 | var_ptr_instruction->value.data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack; | 15342 | result->value.data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack; |
| 15227 | 15343 | ||
| 15228 | return var_ptr_instruction; | 15344 | return result; |
| 15229 | } | 15345 | } |
| 15230 | 15346 | ||
| 15231 | // This function is called when a comptime value becomes accessible at runtime. | 15347 | // This function is called when a comptime value becomes accessible at runtime. |
| ... | @@ -15489,7 +15605,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c | ... | @@ -15489,7 +15605,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15489 | AstNode *body_node = fn_entry->body_node; | 15605 | AstNode *body_node = fn_entry->body_node; |
| 15490 | result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, | 15606 | result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, |
| 15491 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, | 15607 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, |
| 15492 | nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node); | 15608 | nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node, |
| 15609 | UndefOk); | ||
| 15493 | 15610 | ||
| 15494 | if (inferred_err_set_type != nullptr) { | 15611 | if (inferred_err_set_type != nullptr) { |
| 15495 | inferred_err_set_type->data.error_set.infer_fn = nullptr; | 15612 | inferred_err_set_type->data.error_set.infer_fn = nullptr; |
| ... | @@ -15513,8 +15630,9 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c | ... | @@ -15513,8 +15630,9 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15513 | ira->codegen->memoized_fn_eval_table.put(exec_scope, result); | 15630 | ira->codegen->memoized_fn_eval_table.put(exec_scope, result); |
| 15514 | } | 15631 | } |
| 15515 | 15632 | ||
| 15516 | if (type_is_invalid(result->type)) | 15633 | if (type_is_invalid(result->type)) { |
| 15517 | return ira->codegen->invalid_instruction; | 15634 | return ira->codegen->invalid_instruction; |
| 15635 | } | ||
| 15518 | } | 15636 | } |
| 15519 | 15637 | ||
| 15520 | IrInstruction *new_instruction = ir_const(ira, &call_instruction->base, result->type); | 15638 | IrInstruction *new_instruction = ir_const(ira, &call_instruction->base, result->type); |
| ... | @@ -15685,7 +15803,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c | ... | @@ -15685,7 +15803,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15685 | ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, | 15803 | ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, |
| 15686 | fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), | 15804 | fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), |
| 15687 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, | 15805 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, |
| 15688 | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); | 15806 | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, |
| 15807 | nullptr, UndefBad); | ||
| 15689 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, | 15808 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 15690 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); | 15809 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); |
| 15691 | copy_const_val(&const_instruction->base.value, align_result, true); | 15810 | copy_const_val(&const_instruction->base.value, align_result, true); |
| ... | @@ -16066,51 +16185,20 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source | ... | @@ -16066,51 +16185,20 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source |
| 16066 | zig_unreachable(); | 16185 | zig_unreachable(); |
| 16067 | } | 16186 | } |
| 16068 | 16187 | ||
| 16069 | static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { | 16188 | static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *instruction) { |
| 16070 | Error err; | 16189 | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); |
| 16071 | IrInstruction *value = un_op_instruction->value->child; | 16190 | result->value.special = ConstValSpecialLazy; |
| 16072 | ZigType *type_entry = ir_resolve_type(ira, value); | ||
| 16073 | if (type_is_invalid(type_entry)) | ||
| 16074 | return ira->codegen->invalid_instruction; | ||
| 16075 | if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) | ||
| 16076 | return ira->codegen->invalid_instruction; | ||
| 16077 | 16191 | ||
| 16078 | switch (type_entry->id) { | 16192 | LazyValueOptType *lazy_opt_type = allocate<LazyValueOptType>(1); |
| 16079 | case ZigTypeIdInvalid: | 16193 | lazy_opt_type->ira = ira; |
| 16080 | zig_unreachable(); | 16194 | result->value.data.x_lazy = &lazy_opt_type->base; |
| 16081 | case ZigTypeIdMetaType: | 16195 | lazy_opt_type->base.id = LazyValueIdOptType; |
| 16082 | case ZigTypeIdVoid: | ||
| 16083 | case ZigTypeIdBool: | ||
| 16084 | case ZigTypeIdInt: | ||
| 16085 | case ZigTypeIdVector: | ||
| 16086 | case ZigTypeIdFloat: | ||
| 16087 | case ZigTypeIdPointer: | ||
| 16088 | case ZigTypeIdArray: | ||
| 16089 | case ZigTypeIdStruct: | ||
| 16090 | case ZigTypeIdComptimeFloat: | ||
| 16091 | case ZigTypeIdComptimeInt: | ||
| 16092 | case ZigTypeIdEnumLiteral: | ||
| 16093 | case ZigTypeIdUndefined: | ||
| 16094 | case ZigTypeIdNull: | ||
| 16095 | case ZigTypeIdOptional: | ||
| 16096 | case ZigTypeIdErrorUnion: | ||
| 16097 | case ZigTypeIdErrorSet: | ||
| 16098 | case ZigTypeIdEnum: | ||
| 16099 | case ZigTypeIdUnion: | ||
| 16100 | case ZigTypeIdFn: | ||
| 16101 | case ZigTypeIdBoundFn: | ||
| 16102 | case ZigTypeIdArgTuple: | ||
| 16103 | case ZigTypeIdFnFrame: | ||
| 16104 | case ZigTypeIdAnyFrame: | ||
| 16105 | return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry)); | ||
| 16106 | 16196 | ||
| 16107 | case ZigTypeIdUnreachable: | 16197 | lazy_opt_type->payload_type = instruction->value->child; |
| 16108 | case ZigTypeIdOpaque: | 16198 | if (ir_resolve_type_lazy(ira, lazy_opt_type->payload_type) == nullptr) |
| 16109 | ir_add_error_node(ira, un_op_instruction->base.source_node, | 16199 | return ira->codegen->invalid_instruction; |
| 16110 | buf_sprintf("type '%s' not optional", buf_ptr(&type_entry->name))); | 16200 | |
| 16111 | return ira->codegen->invalid_instruction; | 16201 | return result; |
| 16112 | } | ||
| 16113 | zig_unreachable(); | ||
| 16114 | } | 16202 | } |
| 16115 | 16203 | ||
| 16116 | static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *scalar_type, | 16204 | static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *scalar_type, |
| ... | @@ -16727,7 +16815,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -16727,7 +16815,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 16727 | return ira->codegen->invalid_instruction; | 16815 | return ira->codegen->invalid_instruction; |
| 16728 | 16816 | ||
| 16729 | bool safety_check_on = elem_ptr_instruction->safety_check_on; | 16817 | bool safety_check_on = elem_ptr_instruction->safety_check_on; |
| 16730 | if ((err = ensure_complete_type(ira->codegen, return_type->data.pointer.child_type))) | 16818 | if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown))) |
| 16731 | return ira->codegen->invalid_instruction; | 16819 | return ira->codegen->invalid_instruction; |
| 16732 | 16820 | ||
| 16733 | uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); | 16821 | uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); |
| ... | @@ -17005,7 +17093,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, | ... | @@ -17005,7 +17093,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 17005 | auto entry = container_scope->decl_table.maybe_get(field_name); | 17093 | auto entry = container_scope->decl_table.maybe_get(field_name); |
| 17006 | Tld *tld = entry ? entry->value : nullptr; | 17094 | Tld *tld = entry ? entry->value : nullptr; |
| 17007 | if (tld && tld->id == TldIdFn) { | 17095 | if (tld && tld->id == TldIdFn) { |
| 17008 | resolve_top_level_decl(ira->codegen, tld, source_instr->source_node); | 17096 | resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); |
| 17009 | if (tld->resolution == TldResolutionInvalid) | 17097 | if (tld->resolution == TldResolutionInvalid) |
| 17010 | return ira->codegen->invalid_instruction; | 17098 | return ira->codegen->invalid_instruction; |
| 17011 | TldFn *tld_fn = (TldFn *)tld; | 17099 | TldFn *tld_fn = (TldFn *)tld; |
| ... | @@ -17038,6 +17126,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, | ... | @@ -17038,6 +17126,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 17038 | static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, | 17126 | static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| 17039 | TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing) | 17127 | TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing) |
| 17040 | { | 17128 | { |
| 17129 | Error err; | ||
| 17041 | switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { | 17130 | switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { |
| 17042 | case OnePossibleValueInvalid: | 17131 | case OnePossibleValueInvalid: |
| 17043 | return ira->codegen->invalid_instruction; | 17132 | return ira->codegen->invalid_instruction; |
| ... | @@ -17048,9 +17137,9 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction | ... | @@ -17048,9 +17137,9 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction |
| 17048 | case OnePossibleValueNo: | 17137 | case OnePossibleValueNo: |
| 17049 | break; | 17138 | break; |
| 17050 | } | 17139 | } |
| 17140 | if ((err = type_resolve(ira->codegen, struct_type, ResolveStatusAlignmentKnown))) | ||
| 17141 | return ira->codegen->invalid_instruction; | ||
| 17051 | assert(struct_ptr->value.type->id == ZigTypeIdPointer); | 17142 | assert(struct_ptr->value.type->id == ZigTypeIdPointer); |
| 17052 | bool is_packed = (struct_type->data.structure.layout == ContainerLayoutPacked); | ||
| 17053 | uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); | ||
| 17054 | uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host; | 17143 | uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host; |
| 17055 | uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes; | 17144 | uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes; |
| 17056 | uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? | 17145 | uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? |
| ... | @@ -17058,7 +17147,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction | ... | @@ -17058,7 +17147,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction |
| 17058 | bool is_const = struct_ptr->value.type->data.pointer.is_const; | 17147 | bool is_const = struct_ptr->value.type->data.pointer.is_const; |
| 17059 | bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile; | 17148 | bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile; |
| 17060 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, | 17149 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| 17061 | is_const, is_volatile, PtrLenSingle, align_bytes, | 17150 | is_const, is_volatile, PtrLenSingle, field->align, |
| 17062 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), | 17151 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), |
| 17063 | (uint32_t)host_int_bytes_for_result_type, false); | 17152 | (uint32_t)host_int_bytes_for_result_type, false); |
| 17064 | if (instr_is_comptime(struct_ptr)) { | 17153 | if (instr_is_comptime(struct_ptr)) { |
| ... | @@ -17113,7 +17202,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ | ... | @@ -17113,7 +17202,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 17113 | Error err; | 17202 | Error err; |
| 17114 | 17203 | ||
| 17115 | ZigType *bare_type = container_ref_type(container_type); | 17204 | ZigType *bare_type = container_ref_type(container_type); |
| 17116 | if ((err = ensure_complete_type(ira->codegen, bare_type))) | 17205 | if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusSizeKnown))) |
| 17117 | return ira->codegen->invalid_instruction; | 17206 | return ira->codegen->invalid_instruction; |
| 17118 | 17207 | ||
| 17119 | assert(container_ptr->value.type->id == ZigTypeIdPointer); | 17208 | assert(container_ptr->value.type->id == ZigTypeIdPointer); |
| ... | @@ -17243,23 +17332,22 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, | ... | @@ -17243,23 +17332,22 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, |
| 17243 | } | 17332 | } |
| 17244 | 17333 | ||
| 17245 | static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { | 17334 | static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { |
| 17246 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); | 17335 | ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); |
| 17247 | emit_error_notes_for_ref_stack(ira->codegen, msg); | ||
| 17248 | return ira->codegen->invalid_instruction; | 17336 | return ira->codegen->invalid_instruction; |
| 17249 | } | 17337 | } |
| 17250 | 17338 | ||
| 17251 | static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { | 17339 | static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { |
| 17252 | resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node); | 17340 | resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node, true); |
| 17253 | if (tld->resolution == TldResolutionInvalid) | 17341 | if (tld->resolution == TldResolutionInvalid) { |
| 17254 | return ira->codegen->invalid_instruction; | 17342 | return ira->codegen->invalid_instruction; |
| 17343 | } | ||
| 17255 | 17344 | ||
| 17256 | switch (tld->id) { | 17345 | switch (tld->id) { |
| 17257 | case TldIdContainer: | 17346 | case TldIdContainer: |
| 17258 | case TldIdCompTime: | 17347 | case TldIdCompTime: |
| 17259 | case TldIdUsingNamespace: | 17348 | case TldIdUsingNamespace: |
| 17260 | zig_unreachable(); | 17349 | zig_unreachable(); |
| 17261 | case TldIdVar: | 17350 | case TldIdVar: { |
| 17262 | { | ||
| 17263 | TldVar *tld_var = (TldVar *)tld; | 17351 | TldVar *tld_var = (TldVar *)tld; |
| 17264 | ZigVar *var = tld_var->var; | 17352 | ZigVar *var = tld_var->var; |
| 17265 | if (var == nullptr) { | 17353 | if (var == nullptr) { |
| ... | @@ -17271,8 +17359,7 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -17271,8 +17359,7 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ |
| 17271 | 17359 | ||
| 17272 | return ir_get_var_ptr(ira, source_instruction, var); | 17360 | return ir_get_var_ptr(ira, source_instruction, var); |
| 17273 | } | 17361 | } |
| 17274 | case TldIdFn: | 17362 | case TldIdFn: { |
| 17275 | { | ||
| 17276 | TldFn *tld_fn = (TldFn *)tld; | 17363 | TldFn *tld_fn = (TldFn *)tld; |
| 17277 | ZigFn *fn_entry = tld_fn->fn_entry; | 17364 | ZigFn *fn_entry = tld_fn->fn_entry; |
| 17278 | assert(fn_entry->type_entry); | 17365 | assert(fn_entry->type_entry); |
| ... | @@ -17396,7 +17483,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -17396,7 +17483,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc |
| 17396 | return ira->codegen->invalid_instruction; | 17483 | return ira->codegen->invalid_instruction; |
| 17397 | } else if (is_container(child_type)) { | 17484 | } else if (is_container(child_type)) { |
| 17398 | if (child_type->id == ZigTypeIdEnum) { | 17485 | if (child_type->id == ZigTypeIdEnum) { |
| 17399 | if ((err = ensure_complete_type(ira->codegen, child_type))) | 17486 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) |
| 17400 | return ira->codegen->invalid_instruction; | 17487 | return ira->codegen->invalid_instruction; |
| 17401 | 17488 | ||
| 17402 | TypeEnumField *field = find_enum_type_field(child_type, field_name); | 17489 | TypeEnumField *field = find_enum_type_field(child_type, field_name); |
| ... | @@ -17425,7 +17512,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -17425,7 +17512,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc |
| 17425 | (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr || | 17512 | (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr || |
| 17426 | child_type->data.unionation.decl_node->data.container_decl.auto_enum)) | 17513 | child_type->data.unionation.decl_node->data.container_decl.auto_enum)) |
| 17427 | { | 17514 | { |
| 17428 | if ((err = ensure_complete_type(ira->codegen, child_type))) | 17515 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) |
| 17429 | return ira->codegen->invalid_instruction; | 17516 | return ira->codegen->invalid_instruction; |
| 17430 | TypeUnionField *field = find_union_type_field(child_type, field_name); | 17517 | TypeUnionField *field = find_union_type_field(child_type, field_name); |
| 17431 | if (field) { | 17518 | if (field) { |
| ... | @@ -17844,22 +17931,29 @@ static IrInstruction *ir_analyze_instruction_any_frame_type(IrAnalyze *ira, | ... | @@ -17844,22 +17931,29 @@ static IrInstruction *ir_analyze_instruction_any_frame_type(IrAnalyze *ira, |
| 17844 | static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, | 17931 | static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 17845 | IrInstructionSliceType *slice_type_instruction) | 17932 | IrInstructionSliceType *slice_type_instruction) |
| 17846 | { | 17933 | { |
| 17847 | Error err; | 17934 | IrInstruction *result = ir_const(ira, &slice_type_instruction->base, ira->codegen->builtin_types.entry_type); |
| 17848 | uint32_t align_bytes = 0; | 17935 | result->value.special = ConstValSpecialLazy; |
| 17936 | |||
| 17937 | LazyValueSliceType *lazy_slice_type = allocate<LazyValueSliceType>(1); | ||
| 17938 | lazy_slice_type->ira = ira; | ||
| 17939 | result->value.data.x_lazy = &lazy_slice_type->base; | ||
| 17940 | lazy_slice_type->base.id = LazyValueIdSliceType; | ||
| 17941 | |||
| 17849 | if (slice_type_instruction->align_value != nullptr) { | 17942 | if (slice_type_instruction->align_value != nullptr) { |
| 17850 | if (!ir_resolve_align(ira, slice_type_instruction->align_value->child, &align_bytes)) | 17943 | lazy_slice_type->align_inst = slice_type_instruction->align_value->child; |
| 17944 | if (ir_resolve_const(ira, lazy_slice_type->align_inst, LazyOk) == nullptr) | ||
| 17851 | return ira->codegen->invalid_instruction; | 17945 | return ira->codegen->invalid_instruction; |
| 17852 | } | 17946 | } |
| 17853 | 17947 | ||
| 17854 | ZigType *child_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); | 17948 | lazy_slice_type->elem_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); |
| 17855 | if (type_is_invalid(child_type)) | 17949 | if (type_is_invalid(lazy_slice_type->elem_type)) |
| 17856 | return ira->codegen->invalid_instruction; | 17950 | return ira->codegen->invalid_instruction; |
| 17857 | 17951 | ||
| 17858 | bool is_const = slice_type_instruction->is_const; | 17952 | lazy_slice_type->is_const = slice_type_instruction->is_const; |
| 17859 | bool is_volatile = slice_type_instruction->is_volatile; | 17953 | lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; |
| 17860 | bool is_allow_zero = slice_type_instruction->is_allow_zero; | 17954 | lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero; |
| 17861 | 17955 | ||
| 17862 | switch (child_type->id) { | 17956 | switch (lazy_slice_type->elem_type->id) { |
| 17863 | case ZigTypeIdInvalid: // handled above | 17957 | case ZigTypeIdInvalid: // handled above |
| 17864 | zig_unreachable(); | 17958 | zig_unreachable(); |
| 17865 | case ZigTypeIdUnreachable: | 17959 | case ZigTypeIdUnreachable: |
| ... | @@ -17868,7 +17962,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, | ... | @@ -17868,7 +17962,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 17868 | case ZigTypeIdArgTuple: | 17962 | case ZigTypeIdArgTuple: |
| 17869 | case ZigTypeIdOpaque: | 17963 | case ZigTypeIdOpaque: |
| 17870 | ir_add_error_node(ira, slice_type_instruction->base.source_node, | 17964 | ir_add_error_node(ira, slice_type_instruction->base.source_node, |
| 17871 | buf_sprintf("slice of type '%s' not allowed", buf_ptr(&child_type->name))); | 17965 | buf_sprintf("slice of type '%s' not allowed", buf_ptr(&lazy_slice_type->elem_type->name))); |
| 17872 | return ira->codegen->invalid_instruction; | 17966 | return ira->codegen->invalid_instruction; |
| 17873 | case ZigTypeIdMetaType: | 17967 | case ZigTypeIdMetaType: |
| 17874 | case ZigTypeIdVoid: | 17968 | case ZigTypeIdVoid: |
| ... | @@ -17891,18 +17985,9 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, | ... | @@ -17891,18 +17985,9 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 17891 | case ZigTypeIdVector: | 17985 | case ZigTypeIdVector: |
| 17892 | case ZigTypeIdFnFrame: | 17986 | case ZigTypeIdFnFrame: |
| 17893 | case ZigTypeIdAnyFrame: | 17987 | case ZigTypeIdAnyFrame: |
| 17894 | { | 17988 | break; |
| 17895 | ResolveStatus needed_status = (align_bytes == 0) ? | ||
| 17896 | ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; | ||
| 17897 | if ((err = type_resolve(ira->codegen, child_type, needed_status))) | ||
| 17898 | return ira->codegen->invalid_instruction; | ||
| 17899 | ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, | ||
| 17900 | is_const, is_volatile, PtrLenUnknown, align_bytes, 0, 0, is_allow_zero); | ||
| 17901 | ZigType *result_type = get_slice_type(ira->codegen, slice_ptr_type); | ||
| 17902 | return ir_const_type(ira, &slice_type_instruction->base, result_type); | ||
| 17903 | } | ||
| 17904 | } | 17989 | } |
| 17905 | zig_unreachable(); | 17990 | return result; |
| 17906 | } | 17991 | } |
| 17907 | 17992 | ||
| 17908 | static IrInstruction *ir_analyze_instruction_global_asm(IrAnalyze *ira, IrInstructionGlobalAsm *instruction) { | 17993 | static IrInstruction *ir_analyze_instruction_global_asm(IrAnalyze *ira, IrInstructionGlobalAsm *instruction) { |
| ... | @@ -18008,7 +18093,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, | ... | @@ -18008,7 +18093,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, |
| 18008 | case ZigTypeIdFnFrame: | 18093 | case ZigTypeIdFnFrame: |
| 18009 | case ZigTypeIdAnyFrame: | 18094 | case ZigTypeIdAnyFrame: |
| 18010 | { | 18095 | { |
| 18011 | if ((err = ensure_complete_type(ira->codegen, child_type))) | 18096 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) |
| 18012 | return ira->codegen->invalid_instruction; | 18097 | return ira->codegen->invalid_instruction; |
| 18013 | ZigType *result_type = get_array_type(ira->codegen, child_type, size); | 18098 | ZigType *result_type = get_array_type(ira->codegen, child_type, size); |
| 18014 | return ir_const_type(ira, &array_type_instruction->base, result_type); | 18099 | return ir_const_type(ira, &array_type_instruction->base, result_type); |
| ... | @@ -18024,7 +18109,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, | ... | @@ -18024,7 +18109,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, |
| 18024 | IrInstruction *type_value = size_of_instruction->type_value->child; | 18109 | IrInstruction *type_value = size_of_instruction->type_value->child; |
| 18025 | ZigType *type_entry = ir_resolve_type(ira, type_value); | 18110 | ZigType *type_entry = ir_resolve_type(ira, type_value); |
| 18026 | 18111 | ||
| 18027 | if ((err = ensure_complete_type(ira->codegen, type_entry))) | 18112 | if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) |
| 18028 | return ira->codegen->invalid_instruction; | 18113 | return ira->codegen->invalid_instruction; |
| 18029 | 18114 | ||
| 18030 | switch (type_entry->id) { | 18115 | switch (type_entry->id) { |
| ... | @@ -18529,7 +18614,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, | ... | @@ -18529,7 +18614,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 18529 | if (pointee_val->special == ConstValSpecialRuntime) | 18614 | if (pointee_val->special == ConstValSpecialRuntime) |
| 18530 | pointee_val = nullptr; | 18615 | pointee_val = nullptr; |
| 18531 | } | 18616 | } |
| 18532 | if ((err = ensure_complete_type(ira->codegen, target_type))) | 18617 | if ((err = type_resolve(ira->codegen, target_type, ResolveStatusSizeKnown))) |
| 18533 | return ira->codegen->invalid_instruction; | 18618 | return ira->codegen->invalid_instruction; |
| 18534 | 18619 | ||
| 18535 | switch (target_type->id) { | 18620 | switch (target_type->id) { |
| ... | @@ -19070,7 +19155,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -19070,7 +19155,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 19070 | Scope *analyze_scope = &get_container_scope(container_type)->base; | 19155 | Scope *analyze_scope = &get_container_scope(container_type)->base; |
| 19071 | // memoize it | 19156 | // memoize it |
| 19072 | field->init_val = analyze_const_value(ira->codegen, analyze_scope, init_node, | 19157 | field->init_val = analyze_const_value(ira->codegen, analyze_scope, init_node, |
| 19073 | field->type_entry, nullptr); | 19158 | field->type_entry, nullptr, UndefOk); |
| 19074 | } | 19159 | } |
| 19075 | if (type_is_invalid(field->init_val->type)) | 19160 | if (type_is_invalid(field->init_val->type)) |
| 19076 | return ira->codegen->invalid_instruction; | 19161 | return ira->codegen->invalid_instruction; |
| ... | @@ -19276,8 +19361,7 @@ static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, | ... | @@ -19276,8 +19361,7 @@ static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, |
| 19276 | if (!msg_buf) | 19361 | if (!msg_buf) |
| 19277 | return ira->codegen->invalid_instruction; | 19362 | return ira->codegen->invalid_instruction; |
| 19278 | 19363 | ||
| 19279 | ErrorMsg *msg = ir_add_error(ira, &instruction->base, msg_buf); | 19364 | ir_add_error(ira, &instruction->base, msg_buf); |
| 19280 | emit_error_notes_for_ref_stack(ira->codegen, msg); | ||
| 19281 | 19365 | ||
| 19282 | return ira->codegen->invalid_instruction; | 19366 | return ira->codegen->invalid_instruction; |
| 19283 | } | 19367 | } |
| ... | @@ -19319,7 +19403,10 @@ static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruct | ... | @@ -19319,7 +19403,10 @@ static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruct |
| 19319 | ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, | 19403 | ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, |
| 19320 | true, false, PtrLenUnknown, 0, 0, 0, false); | 19404 | true, false, PtrLenUnknown, 0, 0, 0, false); |
| 19321 | ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); | 19405 | ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); |
| 19322 | if (casted_value->value.special == ConstValSpecialStatic) { | 19406 | if (instr_is_comptime(casted_value)) { |
| 19407 | ConstExprValue *val = ir_resolve_const(ira, casted_value, UndefBad); | ||
| 19408 | if (val == nullptr) | ||
| 19409 | return ira->codegen->invalid_instruction; | ||
| 19323 | ErrorTableEntry *err = casted_value->value.data.x_err_set; | 19410 | ErrorTableEntry *err = casted_value->value.data.x_err_set; |
| 19324 | if (!err->cached_error_name_val) { | 19411 | if (!err->cached_error_name_val) { |
| 19325 | ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name); | 19412 | ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name); |
| ... | @@ -19391,7 +19478,7 @@ static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, | ... | @@ -19391,7 +19478,7 @@ static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, |
| 19391 | return ira->codegen->invalid_instruction; | 19478 | return ira->codegen->invalid_instruction; |
| 19392 | } | 19479 | } |
| 19393 | 19480 | ||
| 19394 | if ((err = ensure_complete_type(ira->codegen, container_type))) | 19481 | if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) |
| 19395 | return ira->codegen->invalid_instruction; | 19482 | return ira->codegen->invalid_instruction; |
| 19396 | 19483 | ||
| 19397 | TypeStructField *field = find_struct_type_field(container_type, field_name); | 19484 | TypeStructField *field = find_struct_type_field(container_type, field_name); |
| ... | @@ -19470,7 +19557,7 @@ static TypeStructField *validate_byte_offset(IrAnalyze *ira, | ... | @@ -19470,7 +19557,7 @@ static TypeStructField *validate_byte_offset(IrAnalyze *ira, |
| 19470 | return nullptr; | 19557 | return nullptr; |
| 19471 | 19558 | ||
| 19472 | Error err; | 19559 | Error err; |
| 19473 | if ((err = ensure_complete_type(ira->codegen, container_type))) | 19560 | if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) |
| 19474 | return nullptr; | 19561 | return nullptr; |
| 19475 | 19562 | ||
| 19476 | Buf *field_name = ir_resolve_str(ira, field_name_value); | 19563 | Buf *field_name = ir_resolve_str(ira, field_name_value); |
| ... | @@ -19574,11 +19661,9 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig | ... | @@ -19574,11 +19661,9 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig |
| 19574 | 19661 | ||
| 19575 | ZigVar *var = tld->var; | 19662 | ZigVar *var = tld->var; |
| 19576 | 19663 | ||
| 19577 | if ((err = ensure_complete_type(ira->codegen, var->const_value->type))) | ||
| 19578 | return ira->codegen->builtin_types.entry_invalid; | ||
| 19579 | |||
| 19580 | assert(var->const_value->type->id == ZigTypeIdMetaType); | 19664 | assert(var->const_value->type->id == ZigTypeIdMetaType); |
| 19581 | return var->const_value->data.x_type; | 19665 | |
| 19666 | return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, nullptr, var->const_value); | ||
| 19582 | } | 19667 | } |
| 19583 | 19668 | ||
| 19584 | static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *out_val, | 19669 | static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *out_val, |
| ... | @@ -19594,15 +19679,15 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -19594,15 +19679,15 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr |
| 19594 | ensure_field_index(type_info_declaration_type, "data", 2); | 19679 | ensure_field_index(type_info_declaration_type, "data", 2); |
| 19595 | 19680 | ||
| 19596 | ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type); | 19681 | ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type); |
| 19597 | if ((err = ensure_complete_type(ira->codegen, type_info_declaration_data_type))) | 19682 | if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown))) |
| 19598 | return err; | 19683 | return err; |
| 19599 | 19684 | ||
| 19600 | ZigType *type_info_fn_decl_type = ir_type_info_get_type(ira, "FnDecl", type_info_declaration_data_type); | 19685 | ZigType *type_info_fn_decl_type = ir_type_info_get_type(ira, "FnDecl", type_info_declaration_data_type); |
| 19601 | if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_type))) | 19686 | if ((err = type_resolve(ira->codegen, type_info_fn_decl_type, ResolveStatusSizeKnown))) |
| 19602 | return err; | 19687 | return err; |
| 19603 | 19688 | ||
| 19604 | ZigType *type_info_fn_decl_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_decl_type); | 19689 | ZigType *type_info_fn_decl_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_decl_type); |
| 19605 | if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_inline_type))) | 19690 | if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown))) |
| 19606 | return err; | 19691 | return err; |
| 19607 | 19692 | ||
| 19608 | // Loop through our declarations once to figure out how many declarations we will generate info for. | 19693 | // Loop through our declarations once to figure out how many declarations we will generate info for. |
| ... | @@ -19613,7 +19698,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -19613,7 +19698,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr |
| 19613 | while ((curr_entry = decl_it.next()) != nullptr) { | 19698 | while ((curr_entry = decl_it.next()) != nullptr) { |
| 19614 | // If the declaration is unresolved, force it to be resolved again. | 19699 | // If the declaration is unresolved, force it to be resolved again. |
| 19615 | if (curr_entry->value->resolution == TldResolutionUnresolved) { | 19700 | if (curr_entry->value->resolution == TldResolutionUnresolved) { |
| 19616 | resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node); | 19701 | resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node, false); |
| 19617 | if (curr_entry->value->resolution != TldResolutionOk) { | 19702 | if (curr_entry->value->resolution != TldResolutionOk) { |
| 19618 | return ErrorSemanticAnalyzeFail; | 19703 | return ErrorSemanticAnalyzeFail; |
| 19619 | } | 19704 | } |
| ... | @@ -19673,7 +19758,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -19673,7 +19758,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr |
| 19673 | case TldIdVar: | 19758 | case TldIdVar: |
| 19674 | { | 19759 | { |
| 19675 | ZigVar *var = ((TldVar *)curr_entry->value)->var; | 19760 | ZigVar *var = ((TldVar *)curr_entry->value)->var; |
| 19676 | if ((err = ensure_complete_type(ira->codegen, var->const_value->type))) | 19761 | if ((err = type_resolve(ira->codegen, var->const_value->type, ResolveStatusSizeKnown))) |
| 19677 | return ErrorSemanticAnalyzeFail; | 19762 | return ErrorSemanticAnalyzeFail; |
| 19678 | 19763 | ||
| 19679 | if (var->const_value->type->id == ZigTypeIdMetaType) { | 19764 | if (var->const_value->type->id == ZigTypeIdMetaType) { |
| ... | @@ -19799,7 +19884,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -19799,7 +19884,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr |
| 19799 | case TldIdContainer: | 19884 | case TldIdContainer: |
| 19800 | { | 19885 | { |
| 19801 | ZigType *type_entry = ((TldContainer *)curr_entry->value)->type_entry; | 19886 | ZigType *type_entry = ((TldContainer *)curr_entry->value)->type_entry; |
| 19802 | if ((err = ensure_complete_type(ira->codegen, type_entry))) | 19887 | if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) |
| 19803 | return ErrorSemanticAnalyzeFail; | 19888 | return ErrorSemanticAnalyzeFail; |
| 19804 | 19889 | ||
| 19805 | // This is a type. | 19890 | // This is a type. |
| ... | @@ -19855,7 +19940,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty | ... | @@ -19855,7 +19940,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty |
| 19855 | return nullptr; | 19940 | return nullptr; |
| 19856 | 19941 | ||
| 19857 | ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); | 19942 | ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); |
| 19858 | assertNoError(ensure_complete_type(ira->codegen, type_info_pointer_type)); | 19943 | assertNoError(type_resolve(ira->codegen, type_info_pointer_type, ResolveStatusSizeKnown)); |
| 19859 | 19944 | ||
| 19860 | ConstExprValue *result = create_const_vals(1); | 19945 | ConstExprValue *result = create_const_vals(1); |
| 19861 | result->special = ConstValSpecialStatic; | 19946 | result->special = ConstValSpecialStatic; |
| ... | @@ -19867,7 +19952,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty | ... | @@ -19867,7 +19952,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty |
| 19867 | // size: Size | 19952 | // size: Size |
| 19868 | ensure_field_index(result->type, "size", 0); | 19953 | ensure_field_index(result->type, "size", 0); |
| 19869 | ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); | 19954 | ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); |
| 19870 | assertNoError(ensure_complete_type(ira->codegen, type_info_pointer_size_type)); | 19955 | assertNoError(type_resolve(ira->codegen, type_info_pointer_size_type, ResolveStatusSizeKnown)); |
| 19871 | fields[0].special = ConstValSpecialStatic; | 19956 | fields[0].special = ConstValSpecialStatic; |
| 19872 | fields[0].type = type_info_pointer_size_type; | 19957 | fields[0].type = type_info_pointer_size_type; |
| 19873 | bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index); | 19958 | bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index); |
| ... | @@ -20581,7 +20666,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct | ... | @@ -20581,7 +20666,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct |
| 20581 | ZigType *void_type = ira->codegen->builtin_types.entry_void; | 20666 | ZigType *void_type = ira->codegen->builtin_types.entry_void; |
| 20582 | ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, | 20667 | ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, |
| 20583 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, | 20668 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, |
| 20584 | &cimport_scope->buf, block_node, nullptr, nullptr, nullptr); | 20669 | &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, UndefBad); |
| 20585 | if (type_is_invalid(cimport_result->type)) | 20670 | if (type_is_invalid(cimport_result->type)) |
| 20586 | return ira->codegen->invalid_instruction; | 20671 | return ira->codegen->invalid_instruction; |
| 20587 | 20672 | ||
| ... | @@ -21482,64 +21567,75 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio | ... | @@ -21482,64 +21567,75 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio |
| 21482 | return ira->codegen->invalid_instruction; | 21567 | return ira->codegen->invalid_instruction; |
| 21483 | 21568 | ||
| 21484 | // TODO test this at comptime with u8 and non-u8 types | 21569 | // TODO test this at comptime with u8 and non-u8 types |
| 21485 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && | 21570 | if (instr_is_comptime(casted_dest_ptr) && |
| 21486 | casted_byte->value.special == ConstValSpecialStatic && | 21571 | instr_is_comptime(casted_byte) && |
| 21487 | casted_count->value.special == ConstValSpecialStatic && | 21572 | instr_is_comptime(casted_count)) |
| 21488 | casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && | ||
| 21489 | casted_dest_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) | ||
| 21490 | { | 21573 | { |
| 21491 | ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; | 21574 | ConstExprValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); |
| 21575 | if (dest_ptr_val == nullptr) | ||
| 21576 | return ira->codegen->invalid_instruction; | ||
| 21492 | 21577 | ||
| 21493 | ConstExprValue *dest_elements; | 21578 | ConstExprValue *byte_val = ir_resolve_const(ira, casted_byte, UndefOk); |
| 21494 | size_t start; | 21579 | if (byte_val == nullptr) |
| 21495 | size_t bound_end; | 21580 | return ira->codegen->invalid_instruction; |
| 21496 | switch (dest_ptr_val->data.x_ptr.special) { | ||
| 21497 | case ConstPtrSpecialInvalid: | ||
| 21498 | case ConstPtrSpecialDiscard: | ||
| 21499 | zig_unreachable(); | ||
| 21500 | case ConstPtrSpecialRef: | ||
| 21501 | dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; | ||
| 21502 | start = 0; | ||
| 21503 | bound_end = 1; | ||
| 21504 | break; | ||
| 21505 | case ConstPtrSpecialBaseArray: | ||
| 21506 | { | ||
| 21507 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; | ||
| 21508 | expand_undef_array(ira->codegen, array_val); | ||
| 21509 | dest_elements = array_val->data.x_array.data.s_none.elements; | ||
| 21510 | start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; | ||
| 21511 | bound_end = array_val->type->data.array.len; | ||
| 21512 | break; | ||
| 21513 | } | ||
| 21514 | case ConstPtrSpecialBaseStruct: | ||
| 21515 | zig_panic("TODO memset on const inner struct"); | ||
| 21516 | case ConstPtrSpecialBaseErrorUnionCode: | ||
| 21517 | zig_panic("TODO memset on const inner error union code"); | ||
| 21518 | case ConstPtrSpecialBaseErrorUnionPayload: | ||
| 21519 | zig_panic("TODO memset on const inner error union payload"); | ||
| 21520 | case ConstPtrSpecialBaseOptionalPayload: | ||
| 21521 | zig_panic("TODO memset on const inner optional payload"); | ||
| 21522 | case ConstPtrSpecialHardCodedAddr: | ||
| 21523 | zig_unreachable(); | ||
| 21524 | case ConstPtrSpecialFunction: | ||
| 21525 | zig_panic("TODO memset on ptr cast from function"); | ||
| 21526 | case ConstPtrSpecialNull: | ||
| 21527 | zig_panic("TODO memset on null ptr"); | ||
| 21528 | } | ||
| 21529 | 21581 | ||
| 21530 | size_t count = bigint_as_usize(&casted_count->value.data.x_bigint); | 21582 | ConstExprValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); |
| 21531 | size_t end = start + count; | 21583 | if (count_val == nullptr) |
| 21532 | if (end > bound_end) { | ||
| 21533 | ir_add_error(ira, count_value, buf_sprintf("out of bounds pointer access")); | ||
| 21534 | return ira->codegen->invalid_instruction; | 21584 | return ira->codegen->invalid_instruction; |
| 21535 | } | ||
| 21536 | 21585 | ||
| 21537 | ConstExprValue *byte_val = &casted_byte->value; | 21586 | if (casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && |
| 21538 | for (size_t i = start; i < end; i += 1) { | 21587 | casted_dest_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 21539 | copy_const_val(&dest_elements[i], byte_val, true); | 21588 | { |
| 21540 | } | 21589 | ConstExprValue *dest_elements; |
| 21590 | size_t start; | ||
| 21591 | size_t bound_end; | ||
| 21592 | switch (dest_ptr_val->data.x_ptr.special) { | ||
| 21593 | case ConstPtrSpecialInvalid: | ||
| 21594 | case ConstPtrSpecialDiscard: | ||
| 21595 | zig_unreachable(); | ||
| 21596 | case ConstPtrSpecialRef: | ||
| 21597 | dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; | ||
| 21598 | start = 0; | ||
| 21599 | bound_end = 1; | ||
| 21600 | break; | ||
| 21601 | case ConstPtrSpecialBaseArray: | ||
| 21602 | { | ||
| 21603 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; | ||
| 21604 | expand_undef_array(ira->codegen, array_val); | ||
| 21605 | dest_elements = array_val->data.x_array.data.s_none.elements; | ||
| 21606 | start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; | ||
| 21607 | bound_end = array_val->type->data.array.len; | ||
| 21608 | break; | ||
| 21609 | } | ||
| 21610 | case ConstPtrSpecialBaseStruct: | ||
| 21611 | zig_panic("TODO memset on const inner struct"); | ||
| 21612 | case ConstPtrSpecialBaseErrorUnionCode: | ||
| 21613 | zig_panic("TODO memset on const inner error union code"); | ||
| 21614 | case ConstPtrSpecialBaseErrorUnionPayload: | ||
| 21615 | zig_panic("TODO memset on const inner error union payload"); | ||
| 21616 | case ConstPtrSpecialBaseOptionalPayload: | ||
| 21617 | zig_panic("TODO memset on const inner optional payload"); | ||
| 21618 | case ConstPtrSpecialHardCodedAddr: | ||
| 21619 | zig_unreachable(); | ||
| 21620 | case ConstPtrSpecialFunction: | ||
| 21621 | zig_panic("TODO memset on ptr cast from function"); | ||
| 21622 | case ConstPtrSpecialNull: | ||
| 21623 | zig_panic("TODO memset on null ptr"); | ||
| 21624 | } | ||
| 21541 | 21625 | ||
| 21542 | return ir_const_void(ira, &instruction->base); | 21626 | size_t count = bigint_as_usize(&count_val->data.x_bigint); |
| 21627 | size_t end = start + count; | ||
| 21628 | if (end > bound_end) { | ||
| 21629 | ir_add_error(ira, count_value, buf_sprintf("out of bounds pointer access")); | ||
| 21630 | return ira->codegen->invalid_instruction; | ||
| 21631 | } | ||
| 21632 | |||
| 21633 | for (size_t i = start; i < end; i += 1) { | ||
| 21634 | copy_const_val(&dest_elements[i], byte_val, true); | ||
| 21635 | } | ||
| 21636 | |||
| 21637 | return ir_const_void(ira, &instruction->base); | ||
| 21638 | } | ||
| 21543 | } | 21639 | } |
| 21544 | 21640 | ||
| 21545 | IrInstruction *result = ir_build_memset(&ira->new_irb, instruction->base.scope, instruction->base.source_node, | 21641 | IrInstruction *result = ir_build_memset(&ira->new_irb, instruction->base.scope, instruction->base.source_node, |
| ... | @@ -21607,107 +21703,118 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio | ... | @@ -21607,107 +21703,118 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 21607 | 21703 | ||
| 21608 | // TODO test this at comptime with u8 and non-u8 types | 21704 | // TODO test this at comptime with u8 and non-u8 types |
| 21609 | // TODO test with dest ptr being a global runtime variable | 21705 | // TODO test with dest ptr being a global runtime variable |
| 21610 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && | 21706 | if (instr_is_comptime(casted_dest_ptr) && |
| 21611 | casted_src_ptr->value.special == ConstValSpecialStatic && | 21707 | instr_is_comptime(casted_src_ptr) && |
| 21612 | casted_count->value.special == ConstValSpecialStatic && | 21708 | instr_is_comptime(casted_count)) |
| 21613 | casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) | ||
| 21614 | { | 21709 | { |
| 21615 | size_t count = bigint_as_usize(&casted_count->value.data.x_bigint); | 21710 | ConstExprValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); |
| 21711 | if (dest_ptr_val == nullptr) | ||
| 21712 | return ira->codegen->invalid_instruction; | ||
| 21616 | 21713 | ||
| 21617 | ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; | 21714 | ConstExprValue *src_ptr_val = ir_resolve_const(ira, casted_src_ptr, UndefBad); |
| 21618 | ConstExprValue *dest_elements; | 21715 | if (src_ptr_val == nullptr) |
| 21619 | size_t dest_start; | 21716 | return ira->codegen->invalid_instruction; |
| 21620 | size_t dest_end; | ||
| 21621 | switch (dest_ptr_val->data.x_ptr.special) { | ||
| 21622 | case ConstPtrSpecialInvalid: | ||
| 21623 | case ConstPtrSpecialDiscard: | ||
| 21624 | zig_unreachable(); | ||
| 21625 | case ConstPtrSpecialRef: | ||
| 21626 | dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; | ||
| 21627 | dest_start = 0; | ||
| 21628 | dest_end = 1; | ||
| 21629 | break; | ||
| 21630 | case ConstPtrSpecialBaseArray: | ||
| 21631 | { | ||
| 21632 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; | ||
| 21633 | expand_undef_array(ira->codegen, array_val); | ||
| 21634 | dest_elements = array_val->data.x_array.data.s_none.elements; | ||
| 21635 | dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; | ||
| 21636 | dest_end = array_val->type->data.array.len; | ||
| 21637 | break; | ||
| 21638 | } | ||
| 21639 | case ConstPtrSpecialBaseStruct: | ||
| 21640 | zig_panic("TODO memcpy on const inner struct"); | ||
| 21641 | case ConstPtrSpecialBaseErrorUnionCode: | ||
| 21642 | zig_panic("TODO memcpy on const inner error union code"); | ||
| 21643 | case ConstPtrSpecialBaseErrorUnionPayload: | ||
| 21644 | zig_panic("TODO memcpy on const inner error union payload"); | ||
| 21645 | case ConstPtrSpecialBaseOptionalPayload: | ||
| 21646 | zig_panic("TODO memcpy on const inner optional payload"); | ||
| 21647 | case ConstPtrSpecialHardCodedAddr: | ||
| 21648 | zig_unreachable(); | ||
| 21649 | case ConstPtrSpecialFunction: | ||
| 21650 | zig_panic("TODO memcpy on ptr cast from function"); | ||
| 21651 | case ConstPtrSpecialNull: | ||
| 21652 | zig_panic("TODO memcpy on null ptr"); | ||
| 21653 | } | ||
| 21654 | 21717 | ||
| 21655 | if (dest_start + count > dest_end) { | 21718 | ConstExprValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); |
| 21656 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); | 21719 | if (count_val == nullptr) |
| 21657 | return ira->codegen->invalid_instruction; | 21720 | return ira->codegen->invalid_instruction; |
| 21658 | } | ||
| 21659 | 21721 | ||
| 21660 | ConstExprValue *src_ptr_val = &casted_src_ptr->value; | 21722 | if (dest_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 21661 | ConstExprValue *src_elements; | 21723 | size_t count = bigint_as_usize(&count_val->data.x_bigint); |
| 21662 | size_t src_start; | ||
| 21663 | size_t src_end; | ||
| 21664 | 21724 | ||
| 21665 | switch (src_ptr_val->data.x_ptr.special) { | 21725 | ConstExprValue *dest_elements; |
| 21666 | case ConstPtrSpecialInvalid: | 21726 | size_t dest_start; |
| 21667 | case ConstPtrSpecialDiscard: | 21727 | size_t dest_end; |
| 21668 | zig_unreachable(); | 21728 | switch (dest_ptr_val->data.x_ptr.special) { |
| 21669 | case ConstPtrSpecialRef: | 21729 | case ConstPtrSpecialInvalid: |
| 21670 | src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; | 21730 | case ConstPtrSpecialDiscard: |
| 21671 | src_start = 0; | 21731 | zig_unreachable(); |
| 21672 | src_end = 1; | 21732 | case ConstPtrSpecialRef: |
| 21673 | break; | 21733 | dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; |
| 21674 | case ConstPtrSpecialBaseArray: | 21734 | dest_start = 0; |
| 21675 | { | 21735 | dest_end = 1; |
| 21676 | ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; | ||
| 21677 | expand_undef_array(ira->codegen, array_val); | ||
| 21678 | src_elements = array_val->data.x_array.data.s_none.elements; | ||
| 21679 | src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; | ||
| 21680 | src_end = array_val->type->data.array.len; | ||
| 21681 | break; | 21736 | break; |
| 21682 | } | 21737 | case ConstPtrSpecialBaseArray: |
| 21683 | case ConstPtrSpecialBaseStruct: | 21738 | { |
| 21684 | zig_panic("TODO memcpy on const inner struct"); | 21739 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; |
| 21685 | case ConstPtrSpecialBaseErrorUnionCode: | 21740 | expand_undef_array(ira->codegen, array_val); |
| 21686 | zig_panic("TODO memcpy on const inner error union code"); | 21741 | dest_elements = array_val->data.x_array.data.s_none.elements; |
| 21687 | case ConstPtrSpecialBaseErrorUnionPayload: | 21742 | dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; |
| 21688 | zig_panic("TODO memcpy on const inner error union payload"); | 21743 | dest_end = array_val->type->data.array.len; |
| 21689 | case ConstPtrSpecialBaseOptionalPayload: | 21744 | break; |
| 21690 | zig_panic("TODO memcpy on const inner optional payload"); | 21745 | } |
| 21691 | case ConstPtrSpecialHardCodedAddr: | 21746 | case ConstPtrSpecialBaseStruct: |
| 21692 | zig_unreachable(); | 21747 | zig_panic("TODO memcpy on const inner struct"); |
| 21693 | case ConstPtrSpecialFunction: | 21748 | case ConstPtrSpecialBaseErrorUnionCode: |
| 21694 | zig_panic("TODO memcpy on ptr cast from function"); | 21749 | zig_panic("TODO memcpy on const inner error union code"); |
| 21695 | case ConstPtrSpecialNull: | 21750 | case ConstPtrSpecialBaseErrorUnionPayload: |
| 21696 | zig_panic("TODO memcpy on null ptr"); | 21751 | zig_panic("TODO memcpy on const inner error union payload"); |
| 21697 | } | 21752 | case ConstPtrSpecialBaseOptionalPayload: |
| 21753 | zig_panic("TODO memcpy on const inner optional payload"); | ||
| 21754 | case ConstPtrSpecialHardCodedAddr: | ||
| 21755 | zig_unreachable(); | ||
| 21756 | case ConstPtrSpecialFunction: | ||
| 21757 | zig_panic("TODO memcpy on ptr cast from function"); | ||
| 21758 | case ConstPtrSpecialNull: | ||
| 21759 | zig_panic("TODO memcpy on null ptr"); | ||
| 21760 | } | ||
| 21698 | 21761 | ||
| 21699 | if (src_start + count > src_end) { | 21762 | if (dest_start + count > dest_end) { |
| 21700 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); | 21763 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); |
| 21701 | return ira->codegen->invalid_instruction; | 21764 | return ira->codegen->invalid_instruction; |
| 21702 | } | 21765 | } |
| 21703 | 21766 | ||
| 21704 | // TODO check for noalias violations - this should be generalized to work for any function | 21767 | ConstExprValue *src_elements; |
| 21768 | size_t src_start; | ||
| 21769 | size_t src_end; | ||
| 21705 | 21770 | ||
| 21706 | for (size_t i = 0; i < count; i += 1) { | 21771 | switch (src_ptr_val->data.x_ptr.special) { |
| 21707 | copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); | 21772 | case ConstPtrSpecialInvalid: |
| 21708 | } | 21773 | case ConstPtrSpecialDiscard: |
| 21774 | zig_unreachable(); | ||
| 21775 | case ConstPtrSpecialRef: | ||
| 21776 | src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; | ||
| 21777 | src_start = 0; | ||
| 21778 | src_end = 1; | ||
| 21779 | break; | ||
| 21780 | case ConstPtrSpecialBaseArray: | ||
| 21781 | { | ||
| 21782 | ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; | ||
| 21783 | expand_undef_array(ira->codegen, array_val); | ||
| 21784 | src_elements = array_val->data.x_array.data.s_none.elements; | ||
| 21785 | src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; | ||
| 21786 | src_end = array_val->type->data.array.len; | ||
| 21787 | break; | ||
| 21788 | } | ||
| 21789 | case ConstPtrSpecialBaseStruct: | ||
| 21790 | zig_panic("TODO memcpy on const inner struct"); | ||
| 21791 | case ConstPtrSpecialBaseErrorUnionCode: | ||
| 21792 | zig_panic("TODO memcpy on const inner error union code"); | ||
| 21793 | case ConstPtrSpecialBaseErrorUnionPayload: | ||
| 21794 | zig_panic("TODO memcpy on const inner error union payload"); | ||
| 21795 | case ConstPtrSpecialBaseOptionalPayload: | ||
| 21796 | zig_panic("TODO memcpy on const inner optional payload"); | ||
| 21797 | case ConstPtrSpecialHardCodedAddr: | ||
| 21798 | zig_unreachable(); | ||
| 21799 | case ConstPtrSpecialFunction: | ||
| 21800 | zig_panic("TODO memcpy on ptr cast from function"); | ||
| 21801 | case ConstPtrSpecialNull: | ||
| 21802 | zig_panic("TODO memcpy on null ptr"); | ||
| 21803 | } | ||
| 21709 | 21804 | ||
| 21710 | return ir_const_void(ira, &instruction->base); | 21805 | if (src_start + count > src_end) { |
| 21806 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); | ||
| 21807 | return ira->codegen->invalid_instruction; | ||
| 21808 | } | ||
| 21809 | |||
| 21810 | // TODO check for noalias violations - this should be generalized to work for any function | ||
| 21811 | |||
| 21812 | for (size_t i = 0; i < count; i += 1) { | ||
| 21813 | copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); | ||
| 21814 | } | ||
| 21815 | |||
| 21816 | return ir_const_void(ira, &instruction->base); | ||
| 21817 | } | ||
| 21711 | } | 21818 | } |
| 21712 | 21819 | ||
| 21713 | IrInstruction *result = ir_build_memcpy(&ira->new_irb, instruction->base.scope, instruction->base.source_node, | 21820 | IrInstruction *result = ir_build_memcpy(&ira->new_irb, instruction->base.scope, instruction->base.source_node, |
| ... | @@ -21877,6 +21984,11 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction | ... | @@ -21877,6 +21984,11 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction |
| 21877 | if (slice_ptr == nullptr) | 21984 | if (slice_ptr == nullptr) |
| 21878 | return ira->codegen->invalid_instruction; | 21985 | return ira->codegen->invalid_instruction; |
| 21879 | 21986 | ||
| 21987 | if (slice_ptr->special == ConstValSpecialUndef) { | ||
| 21988 | ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); | ||
| 21989 | return ira->codegen->invalid_instruction; | ||
| 21990 | } | ||
| 21991 | |||
| 21880 | parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index]; | 21992 | parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index]; |
| 21881 | if (parent_ptr->special == ConstValSpecialUndef) { | 21993 | if (parent_ptr->special == ConstValSpecialUndef) { |
| 21882 | ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); | 21994 | ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); |
| ... | @@ -22021,7 +22133,7 @@ static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInst | ... | @@ -22021,7 +22133,7 @@ static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInst |
| 22021 | return ira->codegen->invalid_instruction; | 22133 | return ira->codegen->invalid_instruction; |
| 22022 | ZigType *container_type = ir_resolve_type(ira, container); | 22134 | ZigType *container_type = ir_resolve_type(ira, container); |
| 22023 | 22135 | ||
| 22024 | if ((err = ensure_complete_type(ira->codegen, container_type))) | 22136 | if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) |
| 22025 | return ira->codegen->invalid_instruction; | 22137 | return ira->codegen->invalid_instruction; |
| 22026 | 22138 | ||
| 22027 | uint64_t result; | 22139 | uint64_t result; |
| ... | @@ -22057,7 +22169,7 @@ static IrInstruction *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstr | ... | @@ -22057,7 +22169,7 @@ static IrInstruction *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstr |
| 22057 | if (type_is_invalid(container_type)) | 22169 | if (type_is_invalid(container_type)) |
| 22058 | return ira->codegen->invalid_instruction; | 22170 | return ira->codegen->invalid_instruction; |
| 22059 | 22171 | ||
| 22060 | if ((err = ensure_complete_type(ira->codegen, container_type))) | 22172 | if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) |
| 22061 | return ira->codegen->invalid_instruction; | 22173 | return ira->codegen->invalid_instruction; |
| 22062 | 22174 | ||
| 22063 | 22175 | ||
| ... | @@ -22100,7 +22212,7 @@ static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstr | ... | @@ -22100,7 +22212,7 @@ static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstr |
| 22100 | if (type_is_invalid(container_type)) | 22212 | if (type_is_invalid(container_type)) |
| 22101 | return ira->codegen->invalid_instruction; | 22213 | return ira->codegen->invalid_instruction; |
| 22102 | 22214 | ||
| 22103 | if ((err = ensure_complete_type(ira->codegen, container_type))) | 22215 | if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) |
| 22104 | return ira->codegen->invalid_instruction; | 22216 | return ira->codegen->invalid_instruction; |
| 22105 | 22217 | ||
| 22106 | uint64_t member_index; | 22218 | uint64_t member_index; |
| ... | @@ -22249,53 +22361,24 @@ static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstru | ... | @@ -22249,53 +22361,24 @@ static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstru |
| 22249 | } | 22361 | } |
| 22250 | 22362 | ||
| 22251 | static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { | 22363 | static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { |
| 22252 | Error err; | 22364 | // Here we create a lazy value in order to avoid resolving the alignment of the type |
| 22253 | IrInstruction *type_value = instruction->type_value->child; | 22365 | // immediately. This avoids false positive dependency loops such as: |
| 22254 | if (type_is_invalid(type_value->value.type)) | 22366 | // const Node = struct { |
| 22255 | return ira->codegen->invalid_instruction; | 22367 | // field: []align(@alignOf(Node)) Node, |
| 22256 | ZigType *type_entry = ir_resolve_type(ira, type_value); | 22368 | // }; |
| 22369 | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); | ||
| 22370 | result->value.special = ConstValSpecialLazy; | ||
| 22371 | |||
| 22372 | LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1); | ||
| 22373 | lazy_align_of->ira = ira; | ||
| 22374 | result->value.data.x_lazy = &lazy_align_of->base; | ||
| 22375 | lazy_align_of->base.id = LazyValueIdAlignOf; | ||
| 22257 | 22376 | ||
| 22258 | if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusAlignmentKnown))) | 22377 | lazy_align_of->target_type = instruction->type_value->child; |
| 22378 | if (ir_resolve_type_lazy(ira, lazy_align_of->target_type) == nullptr) | ||
| 22259 | return ira->codegen->invalid_instruction; | 22379 | return ira->codegen->invalid_instruction; |
| 22260 | 22380 | ||
| 22261 | switch (type_entry->id) { | 22381 | return result; |
| 22262 | case ZigTypeIdInvalid: | ||
| 22263 | zig_unreachable(); | ||
| 22264 | case ZigTypeIdMetaType: | ||
| 22265 | case ZigTypeIdUnreachable: | ||
| 22266 | case ZigTypeIdComptimeFloat: | ||
| 22267 | case ZigTypeIdComptimeInt: | ||
| 22268 | case ZigTypeIdEnumLiteral: | ||
| 22269 | case ZigTypeIdUndefined: | ||
| 22270 | case ZigTypeIdNull: | ||
| 22271 | case ZigTypeIdBoundFn: | ||
| 22272 | case ZigTypeIdArgTuple: | ||
| 22273 | case ZigTypeIdVoid: | ||
| 22274 | case ZigTypeIdOpaque: | ||
| 22275 | ir_add_error(ira, instruction->type_value, | ||
| 22276 | buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name))); | ||
| 22277 | return ira->codegen->invalid_instruction; | ||
| 22278 | case ZigTypeIdBool: | ||
| 22279 | case ZigTypeIdInt: | ||
| 22280 | case ZigTypeIdFloat: | ||
| 22281 | case ZigTypeIdPointer: | ||
| 22282 | case ZigTypeIdArray: | ||
| 22283 | case ZigTypeIdStruct: | ||
| 22284 | case ZigTypeIdOptional: | ||
| 22285 | case ZigTypeIdErrorUnion: | ||
| 22286 | case ZigTypeIdErrorSet: | ||
| 22287 | case ZigTypeIdEnum: | ||
| 22288 | case ZigTypeIdUnion: | ||
| 22289 | case ZigTypeIdFn: | ||
| 22290 | case ZigTypeIdVector: | ||
| 22291 | case ZigTypeIdFnFrame: | ||
| 22292 | case ZigTypeIdAnyFrame: | ||
| 22293 | { | ||
| 22294 | uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); | ||
| 22295 | return ir_const_unsigned(ira, &instruction->base, align_in_bytes); | ||
| 22296 | } | ||
| 22297 | } | ||
| 22298 | zig_unreachable(); | ||
| 22299 | } | 22382 | } |
| 22300 | 22383 | ||
| 22301 | static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { | 22384 | static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { |
| ... | @@ -22359,13 +22442,26 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr | ... | @@ -22359,13 +22442,26 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr |
| 22359 | if (type_is_invalid(casted_result_ptr->value.type)) | 22442 | if (type_is_invalid(casted_result_ptr->value.type)) |
| 22360 | return ira->codegen->invalid_instruction; | 22443 | return ira->codegen->invalid_instruction; |
| 22361 | 22444 | ||
| 22362 | if (casted_op1->value.special == ConstValSpecialStatic && | 22445 | if (instr_is_comptime(casted_op1) && |
| 22363 | casted_op2->value.special == ConstValSpecialStatic && | 22446 | instr_is_comptime(casted_op2) && |
| 22364 | casted_result_ptr->value.special == ConstValSpecialStatic) | 22447 | instr_is_comptime(casted_result_ptr)) |
| 22365 | { | 22448 | { |
| 22366 | BigInt *op1_bigint = &casted_op1->value.data.x_bigint; | 22449 | ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); |
| 22367 | BigInt *op2_bigint = &casted_op2->value.data.x_bigint; | 22450 | if (op1_val == nullptr) |
| 22368 | ConstExprValue *pointee_val = const_ptr_pointee(ira, ira->codegen, &casted_result_ptr->value, casted_result_ptr->source_node); | 22451 | return ira->codegen->invalid_instruction; |
| 22452 | |||
| 22453 | ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); | ||
| 22454 | if (op2_val == nullptr) | ||
| 22455 | return ira->codegen->invalid_instruction; | ||
| 22456 | |||
| 22457 | ConstExprValue *result_val = ir_resolve_const(ira, casted_result_ptr, UndefBad); | ||
| 22458 | if (result_val == nullptr) | ||
| 22459 | return ira->codegen->invalid_instruction; | ||
| 22460 | |||
| 22461 | BigInt *op1_bigint = &op1_val->data.x_bigint; | ||
| 22462 | BigInt *op2_bigint = &op2_val->data.x_bigint; | ||
| 22463 | ConstExprValue *pointee_val = const_ptr_pointee(ira, ira->codegen, result_val, | ||
| 22464 | casted_result_ptr->source_node); | ||
| 22369 | if (pointee_val == nullptr) | 22465 | if (pointee_val == nullptr) |
| 22370 | return ira->codegen->invalid_instruction; | 22466 | return ira->codegen->invalid_instruction; |
| 22371 | BigInt *dest_bigint = &pointee_val->data.x_bigint; | 22467 | BigInt *dest_bigint = &pointee_val->data.x_bigint; |
| ... | @@ -22754,84 +22850,64 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct | ... | @@ -22754,84 +22850,64 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct |
| 22754 | AstNode *proto_node = instruction->base.source_node; | 22850 | AstNode *proto_node = instruction->base.source_node; |
| 22755 | assert(proto_node->type == NodeTypeFnProto); | 22851 | assert(proto_node->type == NodeTypeFnProto); |
| 22756 | 22852 | ||
| 22853 | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); | ||
| 22854 | result->value.special = ConstValSpecialLazy; | ||
| 22855 | |||
| 22856 | LazyValueFnType *lazy_fn_type = allocate<LazyValueFnType>(1); | ||
| 22857 | lazy_fn_type->ira = ira; | ||
| 22858 | result->value.data.x_lazy = &lazy_fn_type->base; | ||
| 22859 | lazy_fn_type->base.id = LazyValueIdFnType; | ||
| 22860 | |||
| 22757 | if (proto_node->data.fn_proto.auto_err_set) { | 22861 | if (proto_node->data.fn_proto.auto_err_set) { |
| 22758 | ir_add_error(ira, &instruction->base, | 22862 | ir_add_error(ira, &instruction->base, |
| 22759 | buf_sprintf("inferring error set of return type valid only for function definitions")); | 22863 | buf_sprintf("inferring error set of return type valid only for function definitions")); |
| 22760 | return ira->codegen->invalid_instruction; | 22864 | return ira->codegen->invalid_instruction; |
| 22761 | } | 22865 | } |
| 22762 | 22866 | ||
| 22763 | FnTypeId fn_type_id = {0}; | 22867 | size_t param_count = proto_node->data.fn_proto.params.length; |
| 22764 | init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); | 22868 | lazy_fn_type->proto_node = proto_node; |
| 22869 | lazy_fn_type->param_types = allocate<IrInstruction *>(param_count); | ||
| 22765 | 22870 | ||
| 22766 | for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { | 22871 | for (size_t param_index = 0; param_index < param_count; param_index += 1) { |
| 22767 | AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); | 22872 | AstNode *param_node = proto_node->data.fn_proto.params.at(param_index); |
| 22768 | assert(param_node->type == NodeTypeParamDecl); | 22873 | assert(param_node->type == NodeTypeParamDecl); |
| 22769 | 22874 | ||
| 22770 | bool param_is_var_args = param_node->data.param_decl.is_var_args; | 22875 | bool param_is_var_args = param_node->data.param_decl.is_var_args; |
| 22771 | if (param_is_var_args) { | 22876 | if (param_is_var_args) { |
| 22772 | if (fn_type_id.cc == CallingConventionC) { | 22877 | if (proto_node->data.fn_proto.cc == CallingConventionC) { |
| 22773 | fn_type_id.param_count = fn_type_id.next_param_index; | 22878 | break; |
| 22774 | continue; | 22879 | } else if (proto_node->data.fn_proto.cc == CallingConventionUnspecified) { |
| 22775 | } else if (fn_type_id.cc == CallingConventionUnspecified) { | 22880 | lazy_fn_type->is_generic = true; |
| 22776 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); | 22881 | return result; |
| 22777 | } else { | 22882 | } else { |
| 22778 | zig_unreachable(); | 22883 | zig_unreachable(); |
| 22779 | } | 22884 | } |
| 22780 | } | 22885 | } |
| 22781 | FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; | ||
| 22782 | param_info->is_noalias = param_node->data.param_decl.is_noalias; | ||
| 22783 | 22886 | ||
| 22784 | if (instruction->param_types[fn_type_id.next_param_index] == nullptr) { | 22887 | if (instruction->param_types[param_index] == nullptr) { |
| 22785 | param_info->type = nullptr; | 22888 | lazy_fn_type->is_generic = true; |
| 22786 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); | 22889 | return result; |
| 22787 | } else { | ||
| 22788 | IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->child; | ||
| 22789 | if (type_is_invalid(param_type_value->value.type)) | ||
| 22790 | return ira->codegen->invalid_instruction; | ||
| 22791 | ZigType *param_type = ir_resolve_type(ira, param_type_value); | ||
| 22792 | switch (type_requires_comptime(ira->codegen, param_type)) { | ||
| 22793 | case ReqCompTimeYes: | ||
| 22794 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { | ||
| 22795 | ir_add_error(ira, param_type_value, | ||
| 22796 | buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", | ||
| 22797 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); | ||
| 22798 | return ira->codegen->invalid_instruction; | ||
| 22799 | } | ||
| 22800 | param_info->type = param_type; | ||
| 22801 | fn_type_id.next_param_index += 1; | ||
| 22802 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); | ||
| 22803 | case ReqCompTimeInvalid: | ||
| 22804 | return ira->codegen->invalid_instruction; | ||
| 22805 | case ReqCompTimeNo: | ||
| 22806 | break; | ||
| 22807 | } | ||
| 22808 | if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) { | ||
| 22809 | ir_add_error(ira, param_type_value, | ||
| 22810 | buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", | ||
| 22811 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); | ||
| 22812 | return ira->codegen->invalid_instruction; | ||
| 22813 | } | ||
| 22814 | param_info->type = param_type; | ||
| 22815 | } | 22890 | } |
| 22816 | 22891 | ||
| 22892 | IrInstruction *param_type_value = instruction->param_types[param_index]->child; | ||
| 22893 | if (type_is_invalid(param_type_value->value.type)) | ||
| 22894 | return ira->codegen->invalid_instruction; | ||
| 22895 | if (ir_resolve_const(ira, param_type_value, LazyOk) == nullptr) | ||
| 22896 | return ira->codegen->invalid_instruction; | ||
| 22897 | lazy_fn_type->param_types[param_index] = param_type_value; | ||
| 22817 | } | 22898 | } |
| 22818 | 22899 | ||
| 22819 | if (instruction->align_value != nullptr) { | 22900 | if (instruction->align_value != nullptr) { |
| 22820 | if (!ir_resolve_align(ira, instruction->align_value->child, &fn_type_id.alignment)) | 22901 | lazy_fn_type->align_inst = instruction->align_value->child; |
| 22902 | if (ir_resolve_const(ira, lazy_fn_type->align_inst, LazyOk) == nullptr) | ||
| 22821 | return ira->codegen->invalid_instruction; | 22903 | return ira->codegen->invalid_instruction; |
| 22822 | } | 22904 | } |
| 22823 | 22905 | ||
| 22824 | IrInstruction *return_type_value = instruction->return_type->child; | 22906 | lazy_fn_type->return_type = instruction->return_type->child; |
| 22825 | fn_type_id.return_type = ir_resolve_type(ira, return_type_value); | 22907 | if (ir_resolve_const(ira, lazy_fn_type->return_type, LazyOk) == nullptr) |
| 22826 | if (type_is_invalid(fn_type_id.return_type)) | 22908 | return ira->codegen->invalid_instruction; |
| 22827 | return ira->codegen->invalid_instruction; | ||
| 22828 | if (fn_type_id.return_type->id == ZigTypeIdOpaque) { | ||
| 22829 | ir_add_error(ira, instruction->return_type, | ||
| 22830 | buf_sprintf("return type cannot be opaque")); | ||
| 22831 | return ira->codegen->invalid_instruction; | ||
| 22832 | } | ||
| 22833 | 22909 | ||
| 22834 | return ir_const_type(ira, &instruction->base, get_fn_type(ira->codegen, &fn_type_id)); | 22910 | return result; |
| 22835 | } | 22911 | } |
| 22836 | 22912 | ||
| 22837 | static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { | 22913 | static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { |
| ... | @@ -23218,7 +23294,7 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -23218,7 +23294,7 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ |
| 23218 | if (!val) | 23294 | if (!val) |
| 23219 | return ira->codegen->invalid_instruction; | 23295 | return ira->codegen->invalid_instruction; |
| 23220 | 23296 | ||
| 23221 | if (val->special == ConstValSpecialStatic) { | 23297 | if (value_is_comptime(val) && val->special != ConstValSpecialUndef) { |
| 23222 | bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull || | 23298 | bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull || |
| 23223 | (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && | 23299 | (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && |
| 23224 | val->data.x_ptr.data.hard_coded_addr.addr == 0); | 23300 | val->data.x_ptr.data.hard_coded_addr.addr == 0); |
| ... | @@ -23258,6 +23334,12 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -23258,6 +23334,12 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ |
| 23258 | 23334 | ||
| 23259 | IrInstruction *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); | 23335 | IrInstruction *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); |
| 23260 | 23336 | ||
| 23337 | if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) | ||
| 23338 | return ira->codegen->invalid_instruction; | ||
| 23339 | |||
| 23340 | if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) | ||
| 23341 | return ira->codegen->invalid_instruction; | ||
| 23342 | |||
| 23261 | if (type_has_bits(dest_type) && !type_has_bits(src_type)) { | 23343 | if (type_has_bits(dest_type) && !type_has_bits(src_type)) { |
| 23262 | ErrorMsg *msg = ir_add_error(ira, source_instr, | 23344 | ErrorMsg *msg = ir_add_error(ira, source_instr, |
| 23263 | buf_sprintf("'%s' and '%s' do not have the same in-memory representation", | 23345 | buf_sprintf("'%s' and '%s' do not have the same in-memory representation", |
| ... | @@ -23309,8 +23391,10 @@ static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ConstExp | ... | @@ -23309,8 +23391,10 @@ static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ConstExp |
| 23309 | } | 23391 | } |
| 23310 | 23392 | ||
| 23311 | static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) { | 23393 | static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) { |
| 23312 | if (val->special == ConstValSpecialUndef) | 23394 | if (val->special == ConstValSpecialUndef) { |
| 23395 | expand_undef_struct(codegen, val); | ||
| 23313 | val->special = ConstValSpecialStatic; | 23396 | val->special = ConstValSpecialStatic; |
| 23397 | } | ||
| 23314 | assert(val->special == ConstValSpecialStatic); | 23398 | assert(val->special == ConstValSpecialStatic); |
| 23315 | switch (val->type->id) { | 23399 | switch (val->type->id) { |
| 23316 | case ZigTypeIdInvalid: | 23400 | case ZigTypeIdInvalid: |
| ... | @@ -23746,8 +23830,9 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, | ... | @@ -23746,8 +23830,9 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, |
| 23746 | IrInstructionDeclRef *instruction) | 23830 | IrInstructionDeclRef *instruction) |
| 23747 | { | 23831 | { |
| 23748 | IrInstruction *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base, instruction->tld); | 23832 | IrInstruction *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base, instruction->tld); |
| 23749 | if (type_is_invalid(ref_instruction->value.type)) | 23833 | if (type_is_invalid(ref_instruction->value.type)) { |
| 23750 | return ira->codegen->invalid_instruction; | 23834 | return ira->codegen->invalid_instruction; |
| 23835 | } | ||
| 23751 | 23836 | ||
| 23752 | if (instruction->lval == LValPtr) { | 23837 | if (instruction->lval == LValPtr) { |
| 23753 | return ref_instruction; | 23838 | return ref_instruction; |
| ... | @@ -23795,53 +23880,32 @@ static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstru | ... | @@ -23795,53 +23880,32 @@ static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstru |
| 23795 | } | 23880 | } |
| 23796 | 23881 | ||
| 23797 | static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) { | 23882 | static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) { |
| 23798 | Error err; | 23883 | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); |
| 23799 | ZigType *child_type = ir_resolve_type(ira, instruction->child_type->child); | 23884 | result->value.special = ConstValSpecialLazy; |
| 23800 | if (type_is_invalid(child_type)) | ||
| 23801 | return ira->codegen->invalid_instruction; | ||
| 23802 | 23885 | ||
| 23803 | if (child_type->id == ZigTypeIdUnreachable) { | 23886 | LazyValuePtrType *lazy_ptr_type = allocate<LazyValuePtrType>(1); |
| 23804 | ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed")); | 23887 | lazy_ptr_type->ira = ira; |
| 23805 | return ira->codegen->invalid_instruction; | 23888 | result->value.data.x_lazy = &lazy_ptr_type->base; |
| 23806 | } else if (child_type->id == ZigTypeIdOpaque && instruction->ptr_len == PtrLenUnknown) { | 23889 | lazy_ptr_type->base.id = LazyValueIdPtrType; |
| 23807 | ir_add_error(ira, &instruction->base, buf_sprintf("unknown-length pointer to opaque")); | 23890 | |
| 23891 | lazy_ptr_type->elem_type = instruction->child_type->child; | ||
| 23892 | if (ir_resolve_type_lazy(ira, lazy_ptr_type->elem_type) == nullptr) | ||
| 23808 | return ira->codegen->invalid_instruction; | 23893 | return ira->codegen->invalid_instruction; |
| 23809 | } else if (instruction->ptr_len == PtrLenC) { | ||
| 23810 | if (!type_allowed_in_extern(ira->codegen, child_type)) { | ||
| 23811 | ir_add_error(ira, &instruction->base, | ||
| 23812 | buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", buf_ptr(&child_type->name))); | ||
| 23813 | return ira->codegen->invalid_instruction; | ||
| 23814 | } else if (child_type->id == ZigTypeIdOpaque) { | ||
| 23815 | ir_add_error(ira, &instruction->base, buf_sprintf("C pointers cannot point opaque types")); | ||
| 23816 | return ira->codegen->invalid_instruction; | ||
| 23817 | } else if (instruction->is_allow_zero) { | ||
| 23818 | ir_add_error(ira, &instruction->base, buf_sprintf("C pointers always allow address zero")); | ||
| 23819 | return ira->codegen->invalid_instruction; | ||
| 23820 | } | ||
| 23821 | } | ||
| 23822 | 23894 | ||
| 23823 | uint32_t align_bytes; | ||
| 23824 | if (instruction->align_value != nullptr) { | 23895 | if (instruction->align_value != nullptr) { |
| 23825 | if (!ir_resolve_align(ira, instruction->align_value->child, &align_bytes)) | 23896 | lazy_ptr_type->align_inst = instruction->align_value->child; |
| 23826 | return ira->codegen->invalid_instruction; | 23897 | if (ir_resolve_const(ira, lazy_ptr_type->align_inst, LazyOk) == nullptr) |
| 23827 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusAlignmentKnown))) | ||
| 23828 | return ira->codegen->invalid_instruction; | 23898 | return ira->codegen->invalid_instruction; |
| 23829 | if (!type_has_bits(child_type)) { | ||
| 23830 | align_bytes = 0; | ||
| 23831 | } | ||
| 23832 | } else { | ||
| 23833 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) | ||
| 23834 | return ira->codegen->invalid_instruction; | ||
| 23835 | align_bytes = 0; | ||
| 23836 | } | 23899 | } |
| 23837 | 23900 | ||
| 23838 | bool allow_zero = instruction->is_allow_zero || instruction->ptr_len == PtrLenC; | 23901 | lazy_ptr_type->ptr_len = instruction->ptr_len; |
| 23902 | lazy_ptr_type->is_const = instruction->is_const; | ||
| 23903 | lazy_ptr_type->is_volatile = instruction->is_volatile; | ||
| 23904 | lazy_ptr_type->is_allowzero = instruction->is_allow_zero; | ||
| 23905 | lazy_ptr_type->bit_offset_in_host = instruction->bit_offset_start; | ||
| 23906 | lazy_ptr_type->host_int_bytes = instruction->host_int_bytes; | ||
| 23839 | 23907 | ||
| 23840 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, | 23908 | return result; |
| 23841 | instruction->is_const, instruction->is_volatile, | ||
| 23842 | instruction->ptr_len, align_bytes, | ||
| 23843 | instruction->bit_offset_start, instruction->host_int_bytes, allow_zero); | ||
| 23844 | return ir_const_type(ira, &instruction->base, result_type); | ||
| 23845 | } | 23909 | } |
| 23846 | 23910 | ||
| 23847 | static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstructionAlignCast *instruction) { | 23911 | static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstructionAlignCast *instruction) { |
| ... | @@ -23954,7 +24018,7 @@ static IrInstruction *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstruct | ... | @@ -23954,7 +24018,7 @@ static IrInstruction *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstruct |
| 23954 | return ira->codegen->invalid_instruction; | 24018 | return ira->codegen->invalid_instruction; |
| 23955 | 24019 | ||
| 23956 | if (enum_type->id == ZigTypeIdEnum) { | 24020 | if (enum_type->id == ZigTypeIdEnum) { |
| 23957 | if ((err = ensure_complete_type(ira->codegen, enum_type))) | 24021 | if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) |
| 23958 | return ira->codegen->invalid_instruction; | 24022 | return ira->codegen->invalid_instruction; |
| 23959 | 24023 | ||
| 23960 | return ir_const_type(ira, &instruction->base, enum_type->data.enumeration.tag_int_type); | 24024 | return ir_const_type(ira, &instruction->base, enum_type->data.enumeration.tag_int_type); |
| ... | @@ -25100,7 +25164,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction | ... | @@ -25100,7 +25164,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction |
| 25100 | ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, | 25164 | ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, |
| 25101 | ZigType *expected_type, AstNode *expected_type_source_node) | 25165 | ZigType *expected_type, AstNode *expected_type_source_node) |
| 25102 | { | 25166 | { |
| 25103 | assert(!old_exec->invalid); | 25167 | assert(old_exec->first_err_trace_msg == nullptr); |
| 25104 | assert(expected_type == nullptr || !type_is_invalid(expected_type)); | 25168 | assert(expected_type == nullptr || !type_is_invalid(expected_type)); |
| 25105 | 25169 | ||
| 25106 | IrAnalyze *ira = allocate<IrAnalyze>(1); | 25170 | IrAnalyze *ira = allocate<IrAnalyze>(1); |
| ... | @@ -25147,6 +25211,18 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ | ... | @@ -25147,6 +25211,18 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ |
| 25147 | old_instruction->child = new_instruction; | 25211 | old_instruction->child = new_instruction; |
| 25148 | 25212 | ||
| 25149 | if (type_is_invalid(new_instruction->value.type)) { | 25213 | if (type_is_invalid(new_instruction->value.type)) { |
| 25214 | if (new_exec->first_err_trace_msg != nullptr) { | ||
| 25215 | ira->codegen->trace_err = new_exec->first_err_trace_msg; | ||
| 25216 | } else { | ||
| 25217 | new_exec->first_err_trace_msg = ira->codegen->trace_err; | ||
| 25218 | } | ||
| 25219 | if (new_exec->first_err_trace_msg != nullptr && | ||
| 25220 | !old_instruction->source_node->already_traced_this_node) | ||
| 25221 | { | ||
| 25222 | old_instruction->source_node->already_traced_this_node = true; | ||
| 25223 | new_exec->first_err_trace_msg = add_error_note(ira->codegen, new_exec->first_err_trace_msg, | ||
| 25224 | old_instruction->source_node, buf_create_from_str("referenced here")); | ||
| 25225 | } | ||
| 25150 | return ira->codegen->builtin_types.entry_invalid; | 25226 | return ira->codegen->builtin_types.entry_invalid; |
| 25151 | } | 25227 | } |
| 25152 | 25228 | ||
| ... | @@ -25158,7 +25234,15 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ | ... | @@ -25158,7 +25234,15 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ |
| 25158 | ira->instruction_index += 1; | 25234 | ira->instruction_index += 1; |
| 25159 | } | 25235 | } |
| 25160 | 25236 | ||
| 25161 | if (new_exec->invalid) { | 25237 | if (new_exec->first_err_trace_msg != nullptr) { |
| 25238 | codegen->trace_err = new_exec->first_err_trace_msg; | ||
| 25239 | if (codegen->trace_err != nullptr && new_exec->source_node != nullptr && | ||
| 25240 | !new_exec->source_node->already_traced_this_node) | ||
| 25241 | { | ||
| 25242 | new_exec->source_node->already_traced_this_node = true; | ||
| 25243 | codegen->trace_err = add_error_note(codegen, codegen->trace_err, | ||
| 25244 | new_exec->source_node, buf_create_from_str("referenced here")); | ||
| 25245 | } | ||
| 25162 | return ira->codegen->builtin_types.entry_invalid; | 25246 | return ira->codegen->builtin_types.entry_invalid; |
| 25163 | } else if (ira->src_implicit_return_type_list.length == 0) { | 25247 | } else if (ira->src_implicit_return_type_list.length == 0) { |
| 25164 | return codegen->builtin_types.entry_unreachable; | 25248 | return codegen->builtin_types.entry_unreachable; |
| ... | @@ -25354,3 +25438,269 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -25354,3 +25438,269 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 25354 | } | 25438 | } |
| 25355 | zig_unreachable(); | 25439 | zig_unreachable(); |
| 25356 | } | 25440 | } |
| 25441 | |||
| 25442 | static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, LazyValueFnType *lazy_fn_type) { | ||
| 25443 | Error err; | ||
| 25444 | AstNode *proto_node = lazy_fn_type->proto_node; | ||
| 25445 | |||
| 25446 | FnTypeId fn_type_id = {0}; | ||
| 25447 | init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); | ||
| 25448 | |||
| 25449 | for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { | ||
| 25450 | AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); | ||
| 25451 | assert(param_node->type == NodeTypeParamDecl); | ||
| 25452 | |||
| 25453 | bool param_is_var_args = param_node->data.param_decl.is_var_args; | ||
| 25454 | if (param_is_var_args) { | ||
| 25455 | if (fn_type_id.cc == CallingConventionC) { | ||
| 25456 | fn_type_id.param_count = fn_type_id.next_param_index; | ||
| 25457 | continue; | ||
| 25458 | } else if (fn_type_id.cc == CallingConventionUnspecified) { | ||
| 25459 | return get_generic_fn_type(ira->codegen, &fn_type_id); | ||
| 25460 | } else { | ||
| 25461 | zig_unreachable(); | ||
| 25462 | } | ||
| 25463 | } | ||
| 25464 | FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; | ||
| 25465 | param_info->is_noalias = param_node->data.param_decl.is_noalias; | ||
| 25466 | |||
| 25467 | if (lazy_fn_type->param_types[fn_type_id.next_param_index] == nullptr) { | ||
| 25468 | param_info->type = nullptr; | ||
| 25469 | return get_generic_fn_type(ira->codegen, &fn_type_id); | ||
| 25470 | } else { | ||
| 25471 | IrInstruction *param_type_inst = lazy_fn_type->param_types[fn_type_id.next_param_index]; | ||
| 25472 | ZigType *param_type = ir_resolve_type(ira, param_type_inst); | ||
| 25473 | if (type_is_invalid(param_type)) | ||
| 25474 | return nullptr; | ||
| 25475 | switch (type_requires_comptime(ira->codegen, param_type)) { | ||
| 25476 | case ReqCompTimeYes: | ||
| 25477 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { | ||
| 25478 | ir_add_error(ira, param_type_inst, | ||
| 25479 | buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", | ||
| 25480 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); | ||
| 25481 | return nullptr; | ||
| 25482 | } | ||
| 25483 | param_info->type = param_type; | ||
| 25484 | fn_type_id.next_param_index += 1; | ||
| 25485 | return get_generic_fn_type(ira->codegen, &fn_type_id); | ||
| 25486 | case ReqCompTimeInvalid: | ||
| 25487 | return nullptr; | ||
| 25488 | case ReqCompTimeNo: | ||
| 25489 | break; | ||
| 25490 | } | ||
| 25491 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { | ||
| 25492 | if ((err = type_resolve(ira->codegen, param_type, ResolveStatusZeroBitsKnown))) | ||
| 25493 | return nullptr; | ||
| 25494 | if (!type_has_bits(param_type)) { | ||
| 25495 | ir_add_error(ira, param_type_inst, | ||
| 25496 | buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", | ||
| 25497 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); | ||
| 25498 | return nullptr; | ||
| 25499 | } | ||
| 25500 | } | ||
| 25501 | param_info->type = param_type; | ||
| 25502 | } | ||
| 25503 | } | ||
| 25504 | |||
| 25505 | if (lazy_fn_type->align_inst != nullptr) { | ||
| 25506 | if (!ir_resolve_align(ira, lazy_fn_type->align_inst, &fn_type_id.alignment)) | ||
| 25507 | return nullptr; | ||
| 25508 | } | ||
| 25509 | |||
| 25510 | fn_type_id.return_type = ir_resolve_type(ira, lazy_fn_type->return_type); | ||
| 25511 | if (type_is_invalid(fn_type_id.return_type)) | ||
| 25512 | return nullptr; | ||
| 25513 | if (fn_type_id.return_type->id == ZigTypeIdOpaque) { | ||
| 25514 | ir_add_error(ira, lazy_fn_type->return_type, buf_create_from_str("return type cannot be opaque")); | ||
| 25515 | return nullptr; | ||
| 25516 | } | ||
| 25517 | |||
| 25518 | return get_fn_type(ira->codegen, &fn_type_id); | ||
| 25519 | } | ||
| 25520 | |||
| 25521 | static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) { | ||
| 25522 | Error err; | ||
| 25523 | if (val->special != ConstValSpecialLazy) | ||
| 25524 | return ErrorNone; | ||
| 25525 | switch (val->data.x_lazy->id) { | ||
| 25526 | case LazyValueIdInvalid: | ||
| 25527 | zig_unreachable(); | ||
| 25528 | case LazyValueIdAlignOf: { | ||
| 25529 | LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); | ||
| 25530 | IrAnalyze *ira = lazy_align_of->ira; | ||
| 25531 | |||
| 25532 | if (lazy_align_of->target_type->value.special == ConstValSpecialStatic) { | ||
| 25533 | switch (lazy_align_of->target_type->value.data.x_type->id) { | ||
| 25534 | case ZigTypeIdInvalid: | ||
| 25535 | zig_unreachable(); | ||
| 25536 | case ZigTypeIdMetaType: | ||
| 25537 | case ZigTypeIdUnreachable: | ||
| 25538 | case ZigTypeIdComptimeFloat: | ||
| 25539 | case ZigTypeIdComptimeInt: | ||
| 25540 | case ZigTypeIdEnumLiteral: | ||
| 25541 | case ZigTypeIdUndefined: | ||
| 25542 | case ZigTypeIdNull: | ||
| 25543 | case ZigTypeIdBoundFn: | ||
| 25544 | case ZigTypeIdArgTuple: | ||
| 25545 | case ZigTypeIdVoid: | ||
| 25546 | case ZigTypeIdOpaque: | ||
| 25547 | ir_add_error(ira, lazy_align_of->target_type, | ||
| 25548 | buf_sprintf("no align available for type '%s'", | ||
| 25549 | buf_ptr(&lazy_align_of->target_type->value.data.x_type->name))); | ||
| 25550 | return ErrorSemanticAnalyzeFail; | ||
| 25551 | case ZigTypeIdBool: | ||
| 25552 | case ZigTypeIdInt: | ||
| 25553 | case ZigTypeIdFloat: | ||
| 25554 | case ZigTypeIdPointer: | ||
| 25555 | case ZigTypeIdArray: | ||
| 25556 | case ZigTypeIdStruct: | ||
| 25557 | case ZigTypeIdOptional: | ||
| 25558 | case ZigTypeIdErrorUnion: | ||
| 25559 | case ZigTypeIdErrorSet: | ||
| 25560 | case ZigTypeIdEnum: | ||
| 25561 | case ZigTypeIdUnion: | ||
| 25562 | case ZigTypeIdFn: | ||
| 25563 | case ZigTypeIdVector: | ||
| 25564 | case ZigTypeIdFnFrame: | ||
| 25565 | case ZigTypeIdAnyFrame: | ||
| 25566 | break; | ||
| 25567 | } | ||
| 25568 | } | ||
| 25569 | |||
| 25570 | uint32_t align_in_bytes; | ||
| 25571 | if ((err = type_val_resolve_abi_align(ira->codegen, &lazy_align_of->target_type->value, | ||
| 25572 | &align_in_bytes))) | ||
| 25573 | { | ||
| 25574 | return err; | ||
| 25575 | } | ||
| 25576 | |||
| 25577 | val->special = ConstValSpecialStatic; | ||
| 25578 | assert(val->type->id == ZigTypeIdComptimeInt); | ||
| 25579 | bigint_init_unsigned(&val->data.x_bigint, align_in_bytes); | ||
| 25580 | return ErrorNone; | ||
| 25581 | } | ||
| 25582 | case LazyValueIdSliceType: { | ||
| 25583 | LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy); | ||
| 25584 | IrAnalyze *ira = lazy_slice_type->ira; | ||
| 25585 | |||
| 25586 | uint32_t align_bytes = 0; | ||
| 25587 | if (lazy_slice_type->align_inst != nullptr) { | ||
| 25588 | if (!ir_resolve_align(ira, lazy_slice_type->align_inst, &align_bytes)) | ||
| 25589 | return ErrorSemanticAnalyzeFail; | ||
| 25590 | } | ||
| 25591 | ResolveStatus needed_status = (align_bytes == 0) ? | ||
| 25592 | ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; | ||
| 25593 | if ((err = type_resolve(ira->codegen, lazy_slice_type->elem_type, needed_status))) | ||
| 25594 | return err; | ||
| 25595 | ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, lazy_slice_type->elem_type, | ||
| 25596 | lazy_slice_type->is_const, lazy_slice_type->is_volatile, PtrLenUnknown, align_bytes, | ||
| 25597 | 0, 0, lazy_slice_type->is_allowzero); | ||
| 25598 | val->special = ConstValSpecialStatic; | ||
| 25599 | assert(val->type->id == ZigTypeIdMetaType); | ||
| 25600 | val->data.x_type = get_slice_type(ira->codegen, slice_ptr_type); | ||
| 25601 | return ErrorNone; | ||
| 25602 | } | ||
| 25603 | case LazyValueIdPtrType: { | ||
| 25604 | LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(val->data.x_lazy); | ||
| 25605 | IrAnalyze *ira = lazy_ptr_type->ira; | ||
| 25606 | |||
| 25607 | uint32_t align_bytes = 0; | ||
| 25608 | if (lazy_ptr_type->align_inst != nullptr) { | ||
| 25609 | if (!ir_resolve_align(ira, lazy_ptr_type->align_inst, &align_bytes)) | ||
| 25610 | return ErrorSemanticAnalyzeFail; | ||
| 25611 | } | ||
| 25612 | ZigType *elem_type = ir_resolve_type(ira, lazy_ptr_type->elem_type); | ||
| 25613 | if (type_is_invalid(elem_type)) | ||
| 25614 | return ErrorSemanticAnalyzeFail; | ||
| 25615 | |||
| 25616 | if (elem_type->id == ZigTypeIdUnreachable) { | ||
| 25617 | ir_add_error(ira, lazy_ptr_type->elem_type, | ||
| 25618 | buf_create_from_str("pointer to noreturn not allowed")); | ||
| 25619 | return ErrorSemanticAnalyzeFail; | ||
| 25620 | } else if (elem_type->id == ZigTypeIdOpaque && lazy_ptr_type->ptr_len == PtrLenUnknown) { | ||
| 25621 | ir_add_error(ira, lazy_ptr_type->elem_type, | ||
| 25622 | buf_create_from_str("unknown-length pointer to opaque")); | ||
| 25623 | return ErrorSemanticAnalyzeFail; | ||
| 25624 | } else if (lazy_ptr_type->ptr_len == PtrLenC) { | ||
| 25625 | if (!type_allowed_in_extern(ira->codegen, elem_type)) { | ||
| 25626 | ir_add_error(ira, lazy_ptr_type->elem_type, | ||
| 25627 | buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", | ||
| 25628 | buf_ptr(&elem_type->name))); | ||
| 25629 | return ErrorSemanticAnalyzeFail; | ||
| 25630 | } else if (elem_type->id == ZigTypeIdOpaque) { | ||
| 25631 | ir_add_error(ira, lazy_ptr_type->elem_type, | ||
| 25632 | buf_sprintf("C pointers cannot point opaque types")); | ||
| 25633 | return ErrorSemanticAnalyzeFail; | ||
| 25634 | } else if (lazy_ptr_type->is_allowzero) { | ||
| 25635 | ir_add_error(ira, lazy_ptr_type->elem_type, | ||
| 25636 | buf_sprintf("C pointers always allow address zero")); | ||
| 25637 | return ErrorSemanticAnalyzeFail; | ||
| 25638 | } | ||
| 25639 | } | ||
| 25640 | |||
| 25641 | if (align_bytes != 0) { | ||
| 25642 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) | ||
| 25643 | return err; | ||
| 25644 | if (!type_has_bits(elem_type)) | ||
| 25645 | align_bytes = 0; | ||
| 25646 | } | ||
| 25647 | bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC; | ||
| 25648 | assert(val->type->id == ZigTypeIdMetaType); | ||
| 25649 | val->data.x_type = get_pointer_to_type_extra(ira->codegen, elem_type, | ||
| 25650 | lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes, | ||
| 25651 | lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes, | ||
| 25652 | allow_zero); | ||
| 25653 | val->special = ConstValSpecialStatic; | ||
| 25654 | return ErrorNone; | ||
| 25655 | } | ||
| 25656 | case LazyValueIdOptType: { | ||
| 25657 | LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(val->data.x_lazy); | ||
| 25658 | IrAnalyze *ira = lazy_opt_type->ira; | ||
| 25659 | |||
| 25660 | ZigType *payload_type = ir_resolve_type(ira, lazy_opt_type->payload_type); | ||
| 25661 | if (type_is_invalid(payload_type)) | ||
| 25662 | return ErrorSemanticAnalyzeFail; | ||
| 25663 | |||
| 25664 | if (payload_type->id == ZigTypeIdOpaque || payload_type->id == ZigTypeIdUnreachable) { | ||
| 25665 | ir_add_error(ira, lazy_opt_type->payload_type, | ||
| 25666 | buf_sprintf("type '%s' cannot be optional", buf_ptr(&payload_type->name))); | ||
| 25667 | return ErrorSemanticAnalyzeFail; | ||
| 25668 | } | ||
| 25669 | |||
| 25670 | if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) | ||
| 25671 | return err; | ||
| 25672 | |||
| 25673 | assert(val->type->id == ZigTypeIdMetaType); | ||
| 25674 | val->data.x_type = get_optional_type(ira->codegen, payload_type); | ||
| 25675 | val->special = ConstValSpecialStatic; | ||
| 25676 | return ErrorNone; | ||
| 25677 | } | ||
| 25678 | case LazyValueIdFnType: { | ||
| 25679 | LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(val->data.x_lazy); | ||
| 25680 | ZigType *fn_type = ir_resolve_lazy_fn_type(lazy_fn_type->ira, source_node, lazy_fn_type); | ||
| 25681 | if (fn_type == nullptr) | ||
| 25682 | return ErrorSemanticAnalyzeFail; | ||
| 25683 | val->special = ConstValSpecialStatic; | ||
| 25684 | assert(val->type->id == ZigTypeIdMetaType); | ||
| 25685 | val->data.x_type = fn_type; | ||
| 25686 | return ErrorNone; | ||
| 25687 | } | ||
| 25688 | } | ||
| 25689 | zig_unreachable(); | ||
| 25690 | } | ||
| 25691 | |||
| 25692 | Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) { | ||
| 25693 | Error err; | ||
| 25694 | if ((err = ir_resolve_lazy_raw(source_node, val))) { | ||
| 25695 | if (codegen->trace_err != nullptr && !source_node->already_traced_this_node) { | ||
| 25696 | source_node->already_traced_this_node = true; | ||
| 25697 | codegen->trace_err = add_error_note(codegen, codegen->trace_err, source_node, | ||
| 25698 | buf_create_from_str("referenced here")); | ||
| 25699 | } | ||
| 25700 | return err; | ||
| 25701 | } | ||
| 25702 | if (type_is_invalid(val->type)) { | ||
| 25703 | return ErrorSemanticAnalyzeFail; | ||
| 25704 | } | ||
| 25705 | return ErrorNone; | ||
| 25706 | } |
src/ir.hpp+3-3| ... | @@ -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); |
| 16 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, | 16 | ConstExprValue *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, UndefAllowed undef); |
| 20 | |||
| 21 | Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val); | ||
| 20 | 22 | ||
| 21 | ZigType *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable, | 23 | ZigType *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); |
| ... | @@ -28,6 +30,4 @@ ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprVal | ... | @@ -28,6 +30,4 @@ ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprVal |
| 28 | AstNode *source_node); | 30 | AstNode *source_node); |
| 29 | const char *float_op_to_name(BuiltinFnId op, bool llvm_name); | 31 | const char *float_op_to_name(BuiltinFnId op, bool llvm_name); |
| 30 | 32 | ||
| 31 | void ir_add_analysis_trace(IrAnalyze *ira, ErrorMsg *err_msg, Buf *text); | ||
| 32 | |||
| 33 | #endif | 33 | #endif |
src/tokenizer.cpp+1-1| ... | @@ -841,7 +841,7 @@ void tokenize(Buf *buf, Tokenization *out) { | ... | @@ -841,7 +841,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 841 | case TokenizeStateSawAmpersand: | 841 | case TokenizeStateSawAmpersand: |
| 842 | switch (c) { | 842 | switch (c) { |
| 843 | case '&': | 843 | case '&': |
| 844 | tokenize_error(&t, "`&&` is invalid. Note that `and` is boolean AND."); | 844 | tokenize_error(&t, "`&&` is invalid. Note that `and` is boolean AND"); |
| 845 | break; | 845 | break; |
| 846 | case '=': | 846 | case '=': |
| 847 | set_token_id(&t, t.cur_tok, TokenIdBitAndEq); | 847 | set_token_id(&t, t.cur_tok, TokenIdBitAndEq); |
std/array_list.zig+12-9| ... | @@ -6,20 +6,23 @@ const mem = std.mem; | ... | @@ -6,20 +6,23 @@ const mem = std.mem; |
| 6 | const Allocator = mem.Allocator; | 6 | const Allocator = mem.Allocator; |
| 7 | 7 | ||
| 8 | pub fn ArrayList(comptime T: type) type { | 8 | pub fn ArrayList(comptime T: type) type { |
| 9 | return AlignedArrayList(T, @alignOf(T)); | 9 | return AlignedArrayList(T, null); |
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { | 12 | pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type { |
| 13 | return struct { | 13 | return struct { |
| 14 | const Self = @This(); | 14 | const Self = @This(); |
| 15 | 15 | ||
| 16 | /// Use toSlice instead of slicing this directly, because if you don't | 16 | /// Use toSlice instead of slicing this directly, because if you don't |
| 17 | /// specify the end position of the slice, this will potentially give | 17 | /// specify the end position of the slice, this will potentially give |
| 18 | /// you uninitialized memory. | 18 | /// you uninitialized memory. |
| 19 | items: []align(A) T, | 19 | items: Slice, |
| 20 | len: usize, | 20 | len: usize, |
| 21 | allocator: *Allocator, | 21 | allocator: *Allocator, |
| 22 | 22 | ||
| 23 | pub const Slice = if (alignment) |a| ([]align(a) T) else []T; | ||
| 24 | pub const SliceConst = if (alignment) |a| ([]align(a) const T) else []const T; | ||
| 25 | |||
| 23 | /// Deinitialize with `deinit` or use `toOwnedSlice`. | 26 | /// Deinitialize with `deinit` or use `toOwnedSlice`. |
| 24 | pub fn init(allocator: *Allocator) Self { | 27 | pub fn init(allocator: *Allocator) Self { |
| 25 | return Self{ | 28 | return Self{ |
| ... | @@ -33,11 +36,11 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { | ... | @@ -33,11 +36,11 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { |
| 33 | self.allocator.free(self.items); | 36 | self.allocator.free(self.items); |
| 34 | } | 37 | } |
| 35 | 38 | ||
| 36 | pub fn toSlice(self: Self) []align(A) T { | 39 | pub fn toSlice(self: Self) Slice { |
| 37 | return self.items[0..self.len]; | 40 | return self.items[0..self.len]; |
| 38 | } | 41 | } |
| 39 | 42 | ||
| 40 | pub fn toSliceConst(self: Self) []align(A) const T { | 43 | pub fn toSliceConst(self: Self) SliceConst { |
| 41 | return self.items[0..self.len]; | 44 | return self.items[0..self.len]; |
| 42 | } | 45 | } |
| 43 | 46 | ||
| ... | @@ -69,7 +72,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { | ... | @@ -69,7 +72,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { |
| 69 | /// ArrayList takes ownership of the passed in slice. The slice must have been | 72 | /// ArrayList takes ownership of the passed in slice. The slice must have been |
| 70 | /// allocated with `allocator`. | 73 | /// allocated with `allocator`. |
| 71 | /// Deinitialize with `deinit` or use `toOwnedSlice`. | 74 | /// Deinitialize with `deinit` or use `toOwnedSlice`. |
| 72 | pub fn fromOwnedSlice(allocator: *Allocator, slice: []align(A) T) Self { | 75 | pub fn fromOwnedSlice(allocator: *Allocator, slice: Slice) Self { |
| 73 | return Self{ | 76 | return Self{ |
| 74 | .items = slice, | 77 | .items = slice, |
| 75 | .len = slice.len, | 78 | .len = slice.len, |
| ... | @@ -78,7 +81,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { | ... | @@ -78,7 +81,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { |
| 78 | } | 81 | } |
| 79 | 82 | ||
| 80 | /// The caller owns the returned memory. ArrayList becomes empty. | 83 | /// The caller owns the returned memory. ArrayList becomes empty. |
| 81 | pub fn toOwnedSlice(self: *Self) []align(A) T { | 84 | pub fn toOwnedSlice(self: *Self) Slice { |
| 82 | const allocator = self.allocator; | 85 | const allocator = self.allocator; |
| 83 | const result = allocator.shrink(self.items, self.len); | 86 | const result = allocator.shrink(self.items, self.len); |
| 84 | self.* = init(allocator); | 87 | self.* = init(allocator); |
| ... | @@ -93,7 +96,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { | ... | @@ -93,7 +96,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { |
| 93 | self.items[n] = item; | 96 | self.items[n] = item; |
| 94 | } | 97 | } |
| 95 | 98 | ||
| 96 | pub fn insertSlice(self: *Self, n: usize, items: []align(A) const T) !void { | 99 | pub fn insertSlice(self: *Self, n: usize, items: SliceConst) !void { |
| 97 | try self.ensureCapacity(self.len + items.len); | 100 | try self.ensureCapacity(self.len + items.len); |
| 98 | self.len += items.len; | 101 | self.len += items.len; |
| 99 | 102 | ||
| ... | @@ -141,7 +144,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { | ... | @@ -141,7 +144,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type { |
| 141 | return self.swapRemove(i); | 144 | return self.swapRemove(i); |
| 142 | } | 145 | } |
| 143 | 146 | ||
| 144 | pub fn appendSlice(self: *Self, items: []align(A) const T) !void { | 147 | pub fn appendSlice(self: *Self, items: SliceConst) !void { |
| 145 | try self.ensureCapacity(self.len + items.len); | 148 | try self.ensureCapacity(self.len + items.len); |
| 146 | mem.copy(T, self.items[self.len..], items); | 149 | mem.copy(T, self.items[self.len..], items); |
| 147 | self.len += items.len; | 150 | self.len += items.len; |
test/compile_errors.zig+71-44| ... | @@ -2,6 +2,33 @@ const tests = @import("tests.zig"); | ... | @@ -2,6 +2,33 @@ const tests = @import("tests.zig"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | 3 | ||
| 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { | 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5 | cases.add( | ||
| 6 | "alignment of enum field specified", | ||
| 7 | \\const Number = enum { | ||
| 8 | \\ a, | ||
| 9 | \\ b align(i32), | ||
| 10 | \\}; | ||
| 11 | \\export fn entry1() void { | ||
| 12 | \\ var x: Number = undefined; | ||
| 13 | \\} | ||
| 14 | , | ||
| 15 | "tmp.zig:3:13: error: structs and unions, not enums, support field alignment", | ||
| 16 | "tmp.zig:1:16: note: consider 'union(enum)' here", | ||
| 17 | ); | ||
| 18 | |||
| 19 | cases.add( | ||
| 20 | "bad alignment type", | ||
| 21 | \\export fn entry1() void { | ||
| 22 | \\ var x: []align(true) i32 = undefined; | ||
| 23 | \\} | ||
| 24 | \\export fn entry2() void { | ||
| 25 | \\ var x: *align(f64(12.34)) i32 = undefined; | ||
| 26 | \\} | ||
| 27 | , | ||
| 28 | "tmp.zig:2:20: error: expected type 'u29', found 'bool'", | ||
| 29 | "tmp.zig:5:22: error: fractional component prevents float value 12.340000 from being casted to type 'u29'", | ||
| 30 | ); | ||
| 31 | |||
| 5 | cases.addCase(x: { | 32 | cases.addCase(x: { |
| 6 | var tc = cases.create("variable in inline assembly template cannot be found", | 33 | var tc = cases.create("variable in inline assembly template cannot be found", |
| 7 | \\export fn entry() void { | 34 | \\export fn entry() void { |
| ... | @@ -10,7 +37,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -10,7 +37,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 10 | \\ : [bar] "=r" (-> usize) | 37 | \\ : [bar] "=r" (-> usize) |
| 11 | \\ ); | 38 | \\ ); |
| 12 | \\} | 39 | \\} |
| 13 | , "tmp.zig:2:14: error: could not find 'foo' in the inputs or outputs."); | 40 | , "tmp.zig:2:14: error: could not find 'foo' in the inputs or outputs"); |
| 14 | tc.target = tests.Target{ | 41 | tc.target = tests.Target{ |
| 15 | .Cross = tests.CrossTarget{ | 42 | .Cross = tests.CrossTarget{ |
| 16 | .arch = .x86_64, | 43 | .arch = .x86_64, |
| ... | @@ -53,8 +80,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -53,8 +80,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 53 | \\} | 80 | \\} |
| 54 | , | 81 | , |
| 55 | "tmp.zig:8:1: error: '@Frame(rangeSum)' depends on itself", | 82 | "tmp.zig:8:1: error: '@Frame(rangeSum)' depends on itself", |
| 56 | "tmp.zig:15:33: note: when analyzing type '@Frame(rangeSumIndirect)' here", | 83 | "tmp.zig:15:33: note: when analyzing type '@Frame(rangeSum)' here", |
| 57 | "tmp.zig:26:25: note: when analyzing type '@Frame(rangeSum)' here", | 84 | "tmp.zig:26:25: note: when analyzing type '@Frame(rangeSumIndirect)' here", |
| 58 | ); | 85 | ); |
| 59 | 86 | ||
| 60 | cases.add( | 87 | cases.add( |
| ... | @@ -245,7 +272,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -245,7 +272,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 245 | , | 272 | , |
| 246 | "tmp.zig:4:1: error: unable to determine async function frame of 'amain'", | 273 | "tmp.zig:4:1: error: unable to determine async function frame of 'amain'", |
| 247 | "tmp.zig:5:10: note: analysis of function 'other' depends on the frame", | 274 | "tmp.zig:5:10: note: analysis of function 'other' depends on the frame", |
| 248 | "tmp.zig:8:13: note: depends on the frame here", | 275 | "tmp.zig:8:13: note: referenced here", |
| 249 | ); | 276 | ); |
| 250 | 277 | ||
| 251 | cases.add( | 278 | cases.add( |
| ... | @@ -258,7 +285,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -258,7 +285,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 258 | \\} | 285 | \\} |
| 259 | , | 286 | , |
| 260 | "tmp.zig:4:1: error: cannot resolve '@Frame(amain)': function not fully analyzed yet", | 287 | "tmp.zig:4:1: error: cannot resolve '@Frame(amain)': function not fully analyzed yet", |
| 261 | "tmp.zig:5:13: note: depends on its own frame here", | 288 | "tmp.zig:5:13: note: referenced here", |
| 262 | ); | 289 | ); |
| 263 | 290 | ||
| 264 | cases.add( | 291 | cases.add( |
| ... | @@ -404,7 +431,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -404,7 +431,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 404 | \\ const foo: Foo = undefined; | 431 | \\ const foo: Foo = undefined; |
| 405 | \\} | 432 | \\} |
| 406 | , | 433 | , |
| 407 | "tmp.zig:2:8: error: expected type 'type', found '(undefined)'", | 434 | "tmp.zig:2:8: error: use of undefined value here causes undefined behavior", |
| 408 | ); | 435 | ); |
| 409 | 436 | ||
| 410 | cases.add( | 437 | cases.add( |
| ... | @@ -470,7 +497,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -470,7 +497,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 470 | ); | 497 | ); |
| 471 | 498 | ||
| 472 | cases.add( | 499 | cases.add( |
| 473 | "Generic function where return type is self-referenced", | 500 | "generic function where return type is self-referenced", |
| 474 | \\fn Foo(comptime T: type) Foo(T) { | 501 | \\fn Foo(comptime T: type) Foo(T) { |
| 475 | \\ return struct{ x: T }; | 502 | \\ return struct{ x: T }; |
| 476 | \\} | 503 | \\} |
| ... | @@ -481,7 +508,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -481,7 +508,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 481 | \\} | 508 | \\} |
| 482 | , | 509 | , |
| 483 | "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches", | 510 | "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches", |
| 484 | "tmp.zig:1:29: note: called from here", | 511 | "tmp.zig:5:18: note: referenced here", |
| 485 | ); | 512 | ); |
| 486 | 513 | ||
| 487 | cases.add( | 514 | cases.add( |
| ... | @@ -645,7 +672,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -645,7 +672,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 645 | \\const A = struct { a : A, }; | 672 | \\const A = struct { a : A, }; |
| 646 | \\export fn entry() usize { return @sizeOf(A); } | 673 | \\export fn entry() usize { return @sizeOf(A); } |
| 647 | , | 674 | , |
| 648 | "tmp.zig:1:11: error: struct 'A' contains itself", | 675 | "tmp.zig:1:11: error: struct 'A' depends on itself", |
| 649 | ); | 676 | ); |
| 650 | 677 | ||
| 651 | cases.add( | 678 | cases.add( |
| ... | @@ -655,7 +682,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -655,7 +682,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 655 | \\const C = struct { a : A, }; | 682 | \\const C = struct { a : A, }; |
| 656 | \\export fn entry() usize { return @sizeOf(A); } | 683 | \\export fn entry() usize { return @sizeOf(A); } |
| 657 | , | 684 | , |
| 658 | "tmp.zig:1:11: error: struct 'A' contains itself", | 685 | "tmp.zig:1:11: error: struct 'A' depends on itself", |
| 659 | ); | 686 | ); |
| 660 | 687 | ||
| 661 | cases.add( | 688 | cases.add( |
| ... | @@ -670,7 +697,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -670,7 +697,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 670 | \\ return @sizeOf(@typeOf(foo.x)); | 697 | \\ return @sizeOf(@typeOf(foo.x)); |
| 671 | \\} | 698 | \\} |
| 672 | , | 699 | , |
| 673 | "tmp.zig:1:13: error: struct 'Foo' contains itself", | 700 | "tmp.zig:1:13: error: struct 'Foo' depends on itself", |
| 674 | "tmp.zig:8:28: note: referenced here", | 701 | "tmp.zig:8:28: note: referenced here", |
| 675 | ); | 702 | ); |
| 676 | 703 | ||
| ... | @@ -689,7 +716,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -689,7 +716,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 689 | \\} | 716 | \\} |
| 690 | , | 717 | , |
| 691 | "tmp.zig:7:9: error: dependency loop detected", | 718 | "tmp.zig:7:9: error: dependency loop detected", |
| 692 | "tmp.zig:2:19: note: called from here", | 719 | "tmp.zig:2:19: note: referenced here", |
| 693 | "tmp.zig:10:21: note: referenced here", | 720 | "tmp.zig:10:21: note: referenced here", |
| 694 | ); | 721 | ); |
| 695 | 722 | ||
| ... | @@ -703,7 +730,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -703,7 +730,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 703 | \\ var s: Foo = Foo.E; | 730 | \\ var s: Foo = Foo.E; |
| 704 | \\} | 731 | \\} |
| 705 | , | 732 | , |
| 706 | "tmp.zig:1:17: error: 'Foo' depends on itself", | 733 | "tmp.zig:1:17: error: enum 'Foo' depends on itself", |
| 707 | ); | 734 | ); |
| 708 | 735 | ||
| 709 | cases.add( | 736 | cases.add( |
| ... | @@ -866,7 +893,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -866,7 +893,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 866 | break :x tc; | 893 | break :x tc; |
| 867 | }); | 894 | }); |
| 868 | 895 | ||
| 869 | cases.addTest( | 896 | cases.add( |
| 870 | "export generic function", | 897 | "export generic function", |
| 871 | \\export fn foo(num: var) i32 { | 898 | \\export fn foo(num: var) i32 { |
| 872 | \\ return 0; | 899 | \\ return 0; |
| ... | @@ -875,17 +902,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -875,17 +902,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 875 | "tmp.zig:1:15: error: parameter of type 'var' not allowed in function with calling convention 'ccc'", | 902 | "tmp.zig:1:15: error: parameter of type 'var' not allowed in function with calling convention 'ccc'", |
| 876 | ); | 903 | ); |
| 877 | 904 | ||
| 878 | cases.addTest( | 905 | cases.add( |
| 879 | "C pointer to c_void", | 906 | "C pointer to c_void", |
| 880 | \\export fn a() void { | 907 | \\export fn a() void { |
| 881 | \\ var x: *c_void = undefined; | 908 | \\ var x: *c_void = undefined; |
| 882 | \\ var y: [*c]c_void = x; | 909 | \\ var y: [*c]c_void = x; |
| 883 | \\} | 910 | \\} |
| 884 | , | 911 | , |
| 885 | "tmp.zig:3:12: error: C pointers cannot point opaque types", | 912 | "tmp.zig:3:16: error: C pointers cannot point opaque types", |
| 886 | ); | 913 | ); |
| 887 | 914 | ||
| 888 | cases.addTest( | 915 | cases.add( |
| 889 | "directly embedding opaque type in struct and union", | 916 | "directly embedding opaque type in struct and union", |
| 890 | \\const O = @OpaqueType(); | 917 | \\const O = @OpaqueType(); |
| 891 | \\const Foo = struct { | 918 | \\const Foo = struct { |
| ... | @@ -906,7 +933,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -906,7 +933,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 906 | "tmp.zig:7:10: error: opaque types have unknown size and therefore cannot be directly embedded in unions", | 933 | "tmp.zig:7:10: error: opaque types have unknown size and therefore cannot be directly embedded in unions", |
| 907 | ); | 934 | ); |
| 908 | 935 | ||
| 909 | cases.addTest( | 936 | cases.add( |
| 910 | "implicit cast between C pointer and Zig pointer - bad const/align/child", | 937 | "implicit cast between C pointer and Zig pointer - bad const/align/child", |
| 911 | \\export fn a() void { | 938 | \\export fn a() void { |
| 912 | \\ var x: [*c]u8 = undefined; | 939 | \\ var x: [*c]u8 = undefined; |
| ... | @@ -942,7 +969,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -942,7 +969,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 942 | "tmp.zig:23:22: error: expected type '[*c]u32', found '*u8'", | 969 | "tmp.zig:23:22: error: expected type '[*c]u32', found '*u8'", |
| 943 | ); | 970 | ); |
| 944 | 971 | ||
| 945 | cases.addTest( | 972 | cases.add( |
| 946 | "implicit casting null c pointer to zig pointer", | 973 | "implicit casting null c pointer to zig pointer", |
| 947 | \\comptime { | 974 | \\comptime { |
| 948 | \\ var c_ptr: [*c]u8 = 0; | 975 | \\ var c_ptr: [*c]u8 = 0; |
| ... | @@ -952,7 +979,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -952,7 +979,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 952 | "tmp.zig:3:24: error: null pointer casted to type '*u8'", | 979 | "tmp.zig:3:24: error: null pointer casted to type '*u8'", |
| 953 | ); | 980 | ); |
| 954 | 981 | ||
| 955 | cases.addTest( | 982 | cases.add( |
| 956 | "implicit casting undefined c pointer to zig pointer", | 983 | "implicit casting undefined c pointer to zig pointer", |
| 957 | \\comptime { | 984 | \\comptime { |
| 958 | \\ var c_ptr: [*c]u8 = undefined; | 985 | \\ var c_ptr: [*c]u8 = undefined; |
| ... | @@ -962,7 +989,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -962,7 +989,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 962 | "tmp.zig:3:24: error: use of undefined value here causes undefined behavior", | 989 | "tmp.zig:3:24: error: use of undefined value here causes undefined behavior", |
| 963 | ); | 990 | ); |
| 964 | 991 | ||
| 965 | cases.addTest( | 992 | cases.add( |
| 966 | "implicit casting C pointers which would mess up null semantics", | 993 | "implicit casting C pointers which would mess up null semantics", |
| 967 | \\export fn entry() void { | 994 | \\export fn entry() void { |
| 968 | \\ var slice: []const u8 = "aoeu"; | 995 | \\ var slice: []const u8 = "aoeu"; |
| ... | @@ -987,7 +1014,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -987,7 +1014,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 987 | "tmp.zig:13:35: note: mutable '[*c]const u8' allows illegal null values stored to type '[*]u8'", | 1014 | "tmp.zig:13:35: note: mutable '[*c]const u8' allows illegal null values stored to type '[*]u8'", |
| 988 | ); | 1015 | ); |
| 989 | 1016 | ||
| 990 | cases.addTest( | 1017 | cases.add( |
| 991 | "implicit casting too big integers to C pointers", | 1018 | "implicit casting too big integers to C pointers", |
| 992 | \\export fn a() void { | 1019 | \\export fn a() void { |
| 993 | \\ var ptr: [*c]u8 = (1 << 64) + 1; | 1020 | \\ var ptr: [*c]u8 = (1 << 64) + 1; |
| ... | @@ -1001,14 +1028,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -1001,14 +1028,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1001 | "tmp.zig:6:23: error: integer type 'u65' too big for implicit @intToPtr to type '[*c]u8'", | 1028 | "tmp.zig:6:23: error: integer type 'u65' too big for implicit @intToPtr to type '[*c]u8'", |
| 1002 | ); | 1029 | ); |
| 1003 | 1030 | ||
| 1004 | cases.addTest( | 1031 | cases.add( |
| 1005 | "C pointer pointing to non C ABI compatible type or has align attr", | 1032 | "C pointer pointing to non C ABI compatible type or has align attr", |
| 1006 | \\const Foo = struct {}; | 1033 | \\const Foo = struct {}; |
| 1007 | \\export fn a() void { | 1034 | \\export fn a() void { |
| 1008 | \\ const T = [*c]Foo; | 1035 | \\ const T = [*c]Foo; |
| 1009 | \\} | 1036 | \\} |
| 1010 | , | 1037 | , |
| 1011 | "tmp.zig:3:15: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'", | 1038 | "tmp.zig:3:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'", |
| 1012 | ); | 1039 | ); |
| 1013 | 1040 | ||
| 1014 | cases.addCase(x: { | 1041 | cases.addCase(x: { |
| ... | @@ -1029,7 +1056,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -1029,7 +1056,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1029 | break :x tc; | 1056 | break :x tc; |
| 1030 | }); | 1057 | }); |
| 1031 | 1058 | ||
| 1032 | cases.addTest( | 1059 | cases.add( |
| 1033 | "assign to invalid dereference", | 1060 | "assign to invalid dereference", |
| 1034 | \\export fn entry() void { | 1061 | \\export fn entry() void { |
| 1035 | \\ 'a'.* = 1; | 1062 | \\ 'a'.* = 1; |
| ... | @@ -1038,7 +1065,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -1038,7 +1065,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1038 | "tmp.zig:2:8: error: attempt to dereference non-pointer type 'comptime_int'", | 1065 | "tmp.zig:2:8: error: attempt to dereference non-pointer type 'comptime_int'", |
| 1039 | ); | 1066 | ); |
| 1040 | 1067 | ||
| 1041 | cases.addTest( | 1068 | cases.add( |
| 1042 | "take slice of invalid dereference", | 1069 | "take slice of invalid dereference", |
| 1043 | \\export fn entry() void { | 1070 | \\export fn entry() void { |
| 1044 | \\ const x = 'a'.*[0..]; | 1071 | \\ const x = 'a'.*[0..]; |
| ... | @@ -1047,7 +1074,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -1047,7 +1074,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1047 | "tmp.zig:2:18: error: attempt to dereference non-pointer type 'comptime_int'", | 1074 | "tmp.zig:2:18: error: attempt to dereference non-pointer type 'comptime_int'", |
| 1048 | ); | 1075 | ); |
| 1049 | 1076 | ||
| 1050 | cases.addTest( | 1077 | cases.add( |
| 1051 | "@truncate undefined value", | 1078 | "@truncate undefined value", |
| 1052 | \\export fn entry() void { | 1079 | \\export fn entry() void { |
| 1053 | \\ var z = @truncate(u8, u16(undefined)); | 1080 | \\ var z = @truncate(u8, u16(undefined)); |
| ... | @@ -1091,7 +1118,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -1091,7 +1118,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1091 | \\ return 5678; | 1118 | \\ return 5678; |
| 1092 | \\} | 1119 | \\} |
| 1093 | , | 1120 | , |
| 1094 | "tmp.zig:2:12: error: `&&` is invalid. Note that `and` is boolean AND.", | 1121 | "tmp.zig:2:12: error: `&&` is invalid. Note that `and` is boolean AND", |
| 1095 | ); | 1122 | ); |
| 1096 | 1123 | ||
| 1097 | cases.add( | 1124 | cases.add( |
| ... | @@ -1935,7 +1962,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -1935,7 +1962,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1935 | "unknown length pointer to opaque", | 1962 | "unknown length pointer to opaque", |
| 1936 | \\export const T = [*]@OpaqueType(); | 1963 | \\export const T = [*]@OpaqueType(); |
| 1937 | , | 1964 | , |
| 1938 | "tmp.zig:1:18: error: unknown-length pointer to opaque", | 1965 | "tmp.zig:1:21: error: unknown-length pointer to opaque", |
| 1939 | ); | 1966 | ); |
| 1940 | 1967 | ||
| 1941 | cases.add( | 1968 | cases.add( |
| ... | @@ -2924,7 +2951,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -2924,7 +2951,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2924 | \\fn a() *noreturn {} | 2951 | \\fn a() *noreturn {} |
| 2925 | \\export fn entry() void { _ = a(); } | 2952 | \\export fn entry() void { _ = a(); } |
| 2926 | , | 2953 | , |
| 2927 | "tmp.zig:1:8: error: pointer to noreturn not allowed", | 2954 | "tmp.zig:1:9: error: pointer to noreturn not allowed", |
| 2928 | ); | 2955 | ); |
| 2929 | 2956 | ||
| 2930 | cases.add( | 2957 | cases.add( |
| ... | @@ -3596,7 +3623,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -3596,7 +3623,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 3596 | ); | 3623 | ); |
| 3597 | 3624 | ||
| 3598 | cases.add( | 3625 | cases.add( |
| 3599 | "non constant expression in array size outside function", | 3626 | "non constant expression in array size", |
| 3600 | \\const Foo = struct { | 3627 | \\const Foo = struct { |
| 3601 | \\ y: [get()]u8, | 3628 | \\ y: [get()]u8, |
| 3602 | \\}; | 3629 | \\}; |
| ... | @@ -3606,8 +3633,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -3606,8 +3633,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 3606 | \\export fn entry() usize { return @sizeOf(@typeOf(Foo)); } | 3633 | \\export fn entry() usize { return @sizeOf(@typeOf(Foo)); } |
| 3607 | , | 3634 | , |
| 3608 | "tmp.zig:5:25: error: unable to evaluate constant expression", | 3635 | "tmp.zig:5:25: error: unable to evaluate constant expression", |
| 3609 | "tmp.zig:2:12: note: called from here", | 3636 | "tmp.zig:2:12: note: referenced here", |
| 3610 | "tmp.zig:2:8: note: called from here", | ||
| 3611 | ); | 3637 | ); |
| 3612 | 3638 | ||
| 3613 | cases.add( | 3639 | cases.add( |
| ... | @@ -3701,7 +3727,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -3701,7 +3727,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 3701 | \\export fn entry() usize { return @sizeOf(@typeOf(y)); } | 3727 | \\export fn entry() usize { return @sizeOf(@typeOf(y)); } |
| 3702 | , | 3728 | , |
| 3703 | "tmp.zig:3:14: error: division by zero", | 3729 | "tmp.zig:3:14: error: division by zero", |
| 3704 | "tmp.zig:1:14: note: called from here", | 3730 | "tmp.zig:1:14: note: referenced here", |
| 3705 | ); | 3731 | ); |
| 3706 | 3732 | ||
| 3707 | cases.add( | 3733 | cases.add( |
| ... | @@ -4133,7 +4159,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -4133,7 +4159,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4133 | \\export fn entry() usize { return @sizeOf(@typeOf(seventh_fib_number)); } | 4159 | \\export fn entry() usize { return @sizeOf(@typeOf(seventh_fib_number)); } |
| 4134 | , | 4160 | , |
| 4135 | "tmp.zig:3:21: error: evaluation exceeded 1000 backwards branches", | 4161 | "tmp.zig:3:21: error: evaluation exceeded 1000 backwards branches", |
| 4136 | "tmp.zig:3:21: note: called from here", | 4162 | "tmp.zig:1:37: note: referenced here", |
| 4163 | "tmp.zig:6:50: note: referenced here", | ||
| 4137 | ); | 4164 | ); |
| 4138 | 4165 | ||
| 4139 | cases.add( | 4166 | cases.add( |
| ... | @@ -4174,7 +4201,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -4174,7 +4201,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4174 | \\export fn entry() usize { return @sizeOf(@typeOf(a)); } | 4201 | \\export fn entry() usize { return @sizeOf(@typeOf(a)); } |
| 4175 | , | 4202 | , |
| 4176 | "tmp.zig:6:26: error: unable to evaluate constant expression", | 4203 | "tmp.zig:6:26: error: unable to evaluate constant expression", |
| 4177 | "tmp.zig:4:17: note: called from here", | 4204 | "tmp.zig:4:17: note: referenced here", |
| 4178 | ); | 4205 | ); |
| 4179 | 4206 | ||
| 4180 | cases.add( | 4207 | cases.add( |
| ... | @@ -4257,7 +4284,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -4257,7 +4284,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4257 | \\export fn entry() usize { return @sizeOf(@typeOf(y)); } | 4284 | \\export fn entry() usize { return @sizeOf(@typeOf(y)); } |
| 4258 | , | 4285 | , |
| 4259 | "tmp.zig:3:12: error: negation caused overflow", | 4286 | "tmp.zig:3:12: error: negation caused overflow", |
| 4260 | "tmp.zig:1:14: note: called from here", | 4287 | "tmp.zig:1:14: note: referenced here", |
| 4261 | ); | 4288 | ); |
| 4262 | 4289 | ||
| 4263 | cases.add( | 4290 | cases.add( |
| ... | @@ -4270,7 +4297,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -4270,7 +4297,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4270 | \\export fn entry() usize { return @sizeOf(@typeOf(y)); } | 4297 | \\export fn entry() usize { return @sizeOf(@typeOf(y)); } |
| 4271 | , | 4298 | , |
| 4272 | "tmp.zig:3:14: error: operation caused overflow", | 4299 | "tmp.zig:3:14: error: operation caused overflow", |
| 4273 | "tmp.zig:1:14: note: called from here", | 4300 | "tmp.zig:1:14: note: referenced here", |
| 4274 | ); | 4301 | ); |
| 4275 | 4302 | ||
| 4276 | cases.add( | 4303 | cases.add( |
| ... | @@ -4283,7 +4310,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -4283,7 +4310,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4283 | \\export fn entry() usize { return @sizeOf(@typeOf(y)); } | 4310 | \\export fn entry() usize { return @sizeOf(@typeOf(y)); } |
| 4284 | , | 4311 | , |
| 4285 | "tmp.zig:3:14: error: operation caused overflow", | 4312 | "tmp.zig:3:14: error: operation caused overflow", |
| 4286 | "tmp.zig:1:14: note: called from here", | 4313 | "tmp.zig:1:14: note: referenced here", |
| 4287 | ); | 4314 | ); |
| 4288 | 4315 | ||
| 4289 | cases.add( | 4316 | cases.add( |
| ... | @@ -4296,7 +4323,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -4296,7 +4323,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4296 | \\export fn entry() usize { return @sizeOf(@typeOf(y)); } | 4323 | \\export fn entry() usize { return @sizeOf(@typeOf(y)); } |
| 4297 | , | 4324 | , |
| 4298 | "tmp.zig:3:14: error: operation caused overflow", | 4325 | "tmp.zig:3:14: error: operation caused overflow", |
| 4299 | "tmp.zig:1:14: note: called from here", | 4326 | "tmp.zig:1:14: note: referenced here", |
| 4300 | ); | 4327 | ); |
| 4301 | 4328 | ||
| 4302 | cases.add( | 4329 | cases.add( |
| ... | @@ -4388,7 +4415,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -4388,7 +4415,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4388 | \\} | 4415 | \\} |
| 4389 | , | 4416 | , |
| 4390 | "tmp.zig:3:7: error: unable to evaluate constant expression", | 4417 | "tmp.zig:3:7: error: unable to evaluate constant expression", |
| 4391 | "tmp.zig:16:19: note: called from here", | 4418 | "tmp.zig:16:19: note: referenced here", |
| 4392 | ); | 4419 | ); |
| 4393 | 4420 | ||
| 4394 | cases.add( | 4421 | cases.add( |
| ... | @@ -4717,7 +4744,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -4717,7 +4744,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4717 | \\} | 4744 | \\} |
| 4718 | , | 4745 | , |
| 4719 | "tmp.zig:10:14: error: unable to evaluate constant expression", | 4746 | "tmp.zig:10:14: error: unable to evaluate constant expression", |
| 4720 | "tmp.zig:6:20: note: called from here", | 4747 | "tmp.zig:6:20: note: referenced here", |
| 4721 | ); | 4748 | ); |
| 4722 | 4749 | ||
| 4723 | cases.add( | 4750 | cases.add( |
| ... | @@ -5864,7 +5891,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -5864,7 +5891,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5864 | \\} | 5891 | \\} |
| 5865 | , | 5892 | , |
| 5866 | "tmp.zig:4:25: error: aoeu", | 5893 | "tmp.zig:4:25: error: aoeu", |
| 5867 | "tmp.zig:1:36: note: called from here", | 5894 | "tmp.zig:1:36: note: referenced here", |
| 5868 | "tmp.zig:12:20: note: referenced here", | 5895 | "tmp.zig:12:20: note: referenced here", |
| 5869 | ); | 5896 | ); |
| 5870 | 5897 | ||
| ... | @@ -5939,7 +5966,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -5939,7 +5966,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5939 | \\ var x: MultipleChoice = undefined; | 5966 | \\ var x: MultipleChoice = undefined; |
| 5940 | \\} | 5967 | \\} |
| 5941 | , | 5968 | , |
| 5942 | "tmp.zig:2:14: error: non-enum union field assignment", | 5969 | "tmp.zig:2:14: error: untagged union field assignment", |
| 5943 | "tmp.zig:1:24: note: consider 'union(enum)' here", | 5970 | "tmp.zig:1:24: note: consider 'union(enum)' here", |
| 5944 | ); | 5971 | ); |
| 5945 | 5972 |
test/stage1/behavior/align.zig+15| ... | @@ -290,3 +290,18 @@ test "read 128-bit field from default aligned struct in global memory" { | ... | @@ -290,3 +290,18 @@ test "read 128-bit field from default aligned struct in global memory" { |
| 290 | expect((@ptrToInt(&default_aligned_global.badguy) % 16) == 0); | 290 | expect((@ptrToInt(&default_aligned_global.badguy) % 16) == 0); |
| 291 | expect(12 == default_aligned_global.badguy); | 291 | expect(12 == default_aligned_global.badguy); |
| 292 | } | 292 | } |
| 293 | |||
| 294 | test "struct field explicit alignment" { | ||
| 295 | const S = struct { | ||
| 296 | const Node = struct { | ||
| 297 | next: *Node, | ||
| 298 | massive_byte: u8 align(64), | ||
| 299 | }; | ||
| 300 | }; | ||
| 301 | |||
| 302 | var node: S.Node = undefined; | ||
| 303 | node.massive_byte = 100; | ||
| 304 | expect(node.massive_byte == 100); | ||
| 305 | comptime expect(@typeOf(&node.massive_byte) == *align(64) u8); | ||
| 306 | expect(@ptrToInt(&node.massive_byte) % 64 == 0); | ||
| 307 | } |
test/stage1/behavior/misc.zig+15| ... | @@ -706,3 +706,18 @@ test "result location zero sized array inside struct field implicit cast to slic | ... | @@ -706,3 +706,18 @@ test "result location zero sized array inside struct field implicit cast to slic |
| 706 | var foo = E{ .entries = [_]u32{} }; | 706 | var foo = E{ .entries = [_]u32{} }; |
| 707 | expect(foo.entries.len == 0); | 707 | expect(foo.entries.len == 0); |
| 708 | } | 708 | } |
| 709 | |||
| 710 | var global_foo: *i32 = undefined; | ||
| 711 | |||
| 712 | test "global variable assignment with optional unwrapping with var initialized to undefined" { | ||
| 713 | const S = struct { | ||
| 714 | var data: i32 = 1234; | ||
| 715 | fn foo() ?*i32 { | ||
| 716 | return &data; | ||
| 717 | } | ||
| 718 | }; | ||
| 719 | global_foo = S.foo() orelse { | ||
| 720 | @panic("bad"); | ||
| 721 | }; | ||
| 722 | expect(global_foo.* == 1234); | ||
| 723 | } |