| ... | @@ -22325,63 +22325,24 @@ static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstru | ... | @@ -22325,63 +22325,24 @@ static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstru |
| 22325 | } | 22325 | } |
| 22326 | | 22326 | |
| 22327 | static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { | 22327 | static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { |
| 22328 | IrInstruction *type_value = instruction->type_value->child; | | |
| 22329 | if (type_is_invalid(type_value->value.type)) | | |
| 22330 | return ira->codegen->invalid_instruction; | | |
| 22331 | ZigType *type_entry = ir_resolve_type(ira, type_value); | | |
| 22332 | | | |
| 22333 | switch (type_entry->id) { | | |
| 22334 | case ZigTypeIdInvalid: | | |
| 22335 | zig_unreachable(); | | |
| 22336 | case ZigTypeIdMetaType: | | |
| 22337 | case ZigTypeIdUnreachable: | | |
| 22338 | case ZigTypeIdComptimeFloat: | | |
| 22339 | case ZigTypeIdComptimeInt: | | |
| 22340 | case ZigTypeIdEnumLiteral: | | |
| 22341 | case ZigTypeIdUndefined: | | |
| 22342 | case ZigTypeIdNull: | | |
| 22343 | case ZigTypeIdBoundFn: | | |
| 22344 | case ZigTypeIdArgTuple: | | |
| 22345 | case ZigTypeIdVoid: | | |
| 22346 | case ZigTypeIdOpaque: | | |
| 22347 | ir_add_error(ira, instruction->type_value, | | |
| 22348 | buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name))); | | |
| 22349 | return ira->codegen->invalid_instruction; | | |
| 22350 | case ZigTypeIdBool: | | |
| 22351 | case ZigTypeIdInt: | | |
| 22352 | case ZigTypeIdFloat: | | |
| 22353 | case ZigTypeIdPointer: | | |
| 22354 | case ZigTypeIdArray: | | |
| 22355 | case ZigTypeIdStruct: | | |
| 22356 | case ZigTypeIdOptional: | | |
| 22357 | case ZigTypeIdErrorUnion: | | |
| 22358 | case ZigTypeIdErrorSet: | | |
| 22359 | case ZigTypeIdEnum: | | |
| 22360 | case ZigTypeIdUnion: | | |
| 22361 | case ZigTypeIdFn: | | |
| 22362 | case ZigTypeIdVector: | | |
| 22363 | case ZigTypeIdFnFrame: | | |
| 22364 | case ZigTypeIdAnyFrame: | | |
| 22365 | break; | | |
| 22366 | } | | |
| 22367 | | | |
| 22368 | if (type_is_resolved(type_entry, ResolveStatusAlignmentKnown)) { | | |
| 22369 | uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); | | |
| 22370 | return ir_const_unsigned(ira, &instruction->base, align_in_bytes); | | |
| 22371 | } | | |
| 22372 | | | |
| 22373 | // Here we create a lazy value in order to avoid resolving the alignment of the type | 22328 | // Here we create a lazy value in order to avoid resolving the alignment of the type |
| 22374 | // immediately. This avoids false positive dependency loops such as: | 22329 | // immediately. This avoids false positive dependency loops such as: |
| 22375 | // const Node = struct { | 22330 | // const Node = struct { |
| 22376 | // field: []align(@alignOf(Node)) Node, | 22331 | // field: []align(@alignOf(Node)) Node, |
| 22377 | // }; | 22332 | // }; |
| 22378 | LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1); | | |
| 22379 | lazy_align_of->base.id = LazyValueIdAlignOf; | | |
| 22380 | lazy_align_of->base.exec = ira->new_irb.exec; | | |
| 22381 | lazy_align_of->target_type = type_entry; | | |
| 22382 | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); | 22333 | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); |
| 22383 | result->value.special = ConstValSpecialLazy; | 22334 | result->value.special = ConstValSpecialLazy; |
| | 22335 | |
| | 22336 | LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1); |
| 22384 | result->value.data.x_lazy = &lazy_align_of->base; | 22337 | result->value.data.x_lazy = &lazy_align_of->base; |
| | 22338 | lazy_align_of->base.id = LazyValueIdAlignOf; |
| | 22339 | lazy_align_of->base.exec = ira->new_irb.exec; |
| | 22340 | |
| | 22341 | lazy_align_of->target_type_val = ir_resolve_type_lazy(ira, instruction->type_value->child); |
| | 22342 | if (lazy_align_of->target_type_val == nullptr) |
| | 22343 | return ira->codegen->invalid_instruction; |
| | 22344 | lazy_align_of->target_type_src_node = instruction->type_value->source_node; |
| | 22345 | |
| 22385 | return result; | 22346 | return result; |
| 22386 | } | 22347 | } |
| 22387 | | 22348 | |
| ... | @@ -25530,9 +25491,49 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx | ... | @@ -25530,9 +25491,49 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx |
| 25530 | zig_unreachable(); | 25491 | zig_unreachable(); |
| 25531 | case LazyValueIdAlignOf: { | 25492 | case LazyValueIdAlignOf: { |
| 25532 | LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); | 25493 | LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); |
| 25533 | if ((err = type_resolve(codegen, lazy_align_of->target_type, ResolveStatusAlignmentKnown))) | 25494 | |
| | 25495 | if (lazy_align_of->target_type_val->special == ConstValSpecialStatic) { |
| | 25496 | switch (lazy_align_of->target_type_val->data.x_type->id) { |
| | 25497 | case ZigTypeIdInvalid: |
| | 25498 | zig_unreachable(); |
| | 25499 | case ZigTypeIdMetaType: |
| | 25500 | case ZigTypeIdUnreachable: |
| | 25501 | case ZigTypeIdComptimeFloat: |
| | 25502 | case ZigTypeIdComptimeInt: |
| | 25503 | case ZigTypeIdEnumLiteral: |
| | 25504 | case ZigTypeIdUndefined: |
| | 25505 | case ZigTypeIdNull: |
| | 25506 | case ZigTypeIdBoundFn: |
| | 25507 | case ZigTypeIdArgTuple: |
| | 25508 | case ZigTypeIdVoid: |
| | 25509 | case ZigTypeIdOpaque: |
| | 25510 | exec_add_error_node(codegen, exec, lazy_align_of->target_type_src_node, |
| | 25511 | buf_sprintf("no align available for type '%s'", |
| | 25512 | buf_ptr(&lazy_align_of->target_type_val->data.x_type->name))); |
| | 25513 | return ErrorSemanticAnalyzeFail; |
| | 25514 | case ZigTypeIdBool: |
| | 25515 | case ZigTypeIdInt: |
| | 25516 | case ZigTypeIdFloat: |
| | 25517 | case ZigTypeIdPointer: |
| | 25518 | case ZigTypeIdArray: |
| | 25519 | case ZigTypeIdStruct: |
| | 25520 | case ZigTypeIdOptional: |
| | 25521 | case ZigTypeIdErrorUnion: |
| | 25522 | case ZigTypeIdErrorSet: |
| | 25523 | case ZigTypeIdEnum: |
| | 25524 | case ZigTypeIdUnion: |
| | 25525 | case ZigTypeIdFn: |
| | 25526 | case ZigTypeIdVector: |
| | 25527 | case ZigTypeIdFnFrame: |
| | 25528 | case ZigTypeIdAnyFrame: |
| | 25529 | break; |
| | 25530 | } |
| | 25531 | } |
| | 25532 | |
| | 25533 | uint32_t align_in_bytes; |
| | 25534 | if ((err = type_val_resolve_abi_align(codegen, lazy_align_of->target_type_val, &align_in_bytes))) |
| 25534 | return err; | 25535 | return err; |
| 25535 | uint64_t align_in_bytes = get_abi_alignment(codegen, lazy_align_of->target_type); | 25536 | |
| 25536 | val->special = ConstValSpecialStatic; | 25537 | val->special = ConstValSpecialStatic; |
| 25537 | assert(val->type->id == ZigTypeIdComptimeInt); | 25538 | assert(val->type->id == ZigTypeIdComptimeInt); |
| 25538 | bigint_init_unsigned(&val->data.x_bigint, align_in_bytes); | 25539 | bigint_init_unsigned(&val->data.x_bigint, align_in_bytes); |