| ... | ... | @@ -22325,63 +22325,24 @@ static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstru |
| 22325 | 22325 | } |
| 22326 | 22326 | |
| 22327 | 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 | 22328 | // Here we create a lazy value in order to avoid resolving the alignment of the type |
| 22374 | 22329 | // immediately. This avoids false positive dependency loops such as: |
| 22375 | 22330 | // const Node = struct { |
| 22376 | 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 | 22333 | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); |
| 22383 | 22334 | result->value.special = ConstValSpecialLazy; |
| 22335 | |
| 22336 | LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1); |
| 22384 | 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 | 22346 | return result; |
| 22386 | 22347 | } |
| 22387 | 22348 | |
| ... | ... | @@ -25530,9 +25491,49 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx |
| 25530 | 25491 | zig_unreachable(); |
| 25531 | 25492 | case LazyValueIdAlignOf: { |
| 25532 | 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 | 25535 | return err; |
| 25535 | | uint64_t align_in_bytes = get_abi_alignment(codegen, lazy_align_of->target_type); |
| 25536 | |
| 25536 | 25537 | val->special = ConstValSpecialStatic; |
| 25537 | 25538 | assert(val->type->id == ZigTypeIdComptimeInt); |
| 25538 | 25539 | bigint_init_unsigned(&val->data.x_bigint, align_in_bytes); |