| author | |
| committer | |
| log | f55fdc00fcde3cd17ed0ddb94c0997c882dbe6b9 |
| tree | 911f875f15548275274e6811464850e3191b06b1 |
| parent | 84619abe9f16bc030c5bdb888f47a9b49b87c2ff |
in the expression `&const a.b`, the const (and/or volatile)
qualifiers would be incorrectly dropped.
closes #6558 files changed, 39 insertions(+), 12 deletions(-)
doc/docgen.zig+1-1| ... | @@ -42,7 +42,7 @@ const State = enum { | ... | @@ -42,7 +42,7 @@ const State = enum { |
| 42 | 42 | ||
| 43 | // TODO look for code segments | 43 | // TODO look for code segments |
| 44 | 44 | ||
| 45 | fn gen(in: &io.InStream, out: &const io.OutStream) { | 45 | fn gen(in: &io.InStream, out: &io.OutStream) { |
| 46 | var state = State.Start; | 46 | var state = State.Start; |
| 47 | while (true) { | 47 | while (true) { |
| 48 | const byte = in.readByte() %% |err| { | 48 | const byte = in.readByte() %% |err| { |
src/ir.cpp+16-7| ... | @@ -1025,7 +1025,7 @@ static IrInstruction *ir_build_ptr_type_of(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -1025,7 +1025,7 @@ static IrInstruction *ir_build_ptr_type_of(IrBuilder *irb, Scope *scope, AstNode |
| 1025 | ptr_type_of_instruction->bit_offset_start = bit_offset_start; | 1025 | ptr_type_of_instruction->bit_offset_start = bit_offset_start; |
| 1026 | ptr_type_of_instruction->bit_offset_end = bit_offset_end; | 1026 | ptr_type_of_instruction->bit_offset_end = bit_offset_end; |
| 1027 | 1027 | ||
| 1028 | ir_ref_instruction(align_value, irb->current_basic_block); | 1028 | if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); |
| 1029 | ir_ref_instruction(child_type, irb->current_basic_block); | 1029 | ir_ref_instruction(child_type, irb->current_basic_block); |
| 1030 | 1030 | ||
| 1031 | return &ptr_type_of_instruction->base; | 1031 | return &ptr_type_of_instruction->base; |
| ... | @@ -4897,13 +4897,18 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -4897,13 +4897,18 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n |
| 4897 | AstNode *expr_node = node->data.addr_of_expr.op_expr; | 4897 | AstNode *expr_node = node->data.addr_of_expr.op_expr; |
| 4898 | AstNode *align_expr = node->data.addr_of_expr.align_expr; | 4898 | AstNode *align_expr = node->data.addr_of_expr.align_expr; |
| 4899 | 4899 | ||
| 4900 | if (align_expr == nullptr) { | 4900 | if (align_expr == nullptr && !is_const && !is_volatile) { |
| 4901 | return ir_gen_node_extra(irb, expr_node, scope, make_lval_addr(is_const, is_volatile)); | 4901 | return ir_gen_node_extra(irb, expr_node, scope, make_lval_addr(is_const, is_volatile)); |
| 4902 | } | 4902 | } |
| 4903 | 4903 | ||
| 4904 | IrInstruction *align_value = ir_gen_node(irb, align_expr, scope); | 4904 | IrInstruction *align_value; |
| 4905 | if (align_value == irb->codegen->invalid_instruction) | 4905 | if (align_expr != nullptr) { |
| 4906 | return align_value; | 4906 | align_value = ir_gen_node(irb, align_expr, scope); |
| 4907 | if (align_value == irb->codegen->invalid_instruction) | ||
| 4908 | return align_value; | ||
| 4909 | } else { | ||
| 4910 | align_value = nullptr; | ||
| 4911 | } | ||
| 4907 | 4912 | ||
| 4908 | IrInstruction *child_type = ir_gen_node(irb, expr_node, scope); | 4913 | IrInstruction *child_type = ir_gen_node(irb, expr_node, scope); |
| 4909 | if (child_type == irb->codegen->invalid_instruction) | 4914 | if (child_type == irb->codegen->invalid_instruction) |
| ... | @@ -15959,8 +15964,12 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_of(IrAnalyze *ira, IrInst | ... | @@ -15959,8 +15964,12 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_of(IrAnalyze *ira, IrInst |
| 15959 | return ira->codegen->builtin_types.entry_invalid; | 15964 | return ira->codegen->builtin_types.entry_invalid; |
| 15960 | 15965 | ||
| 15961 | uint32_t align_bytes; | 15966 | uint32_t align_bytes; |
| 15962 | if (!ir_resolve_align(ira, instruction->align_value->other, &align_bytes)) | 15967 | if (instruction->align_value != nullptr) { |
| 15963 | return ira->codegen->builtin_types.entry_invalid; | 15968 | if (!ir_resolve_align(ira, instruction->align_value->other, &align_bytes)) |
| 15969 | return ira->codegen->builtin_types.entry_invalid; | ||
| 15970 | } else { | ||
| 15971 | align_bytes = get_abi_alignment(ira->codegen, child_type); | ||
| 15972 | } | ||
| 15964 | 15973 | ||
| 15965 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 15974 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 15966 | out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type, | 15975 | out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type, |
src/ir_print.cpp+6-2| ... | @@ -886,8 +886,12 @@ static void ir_print_can_implicit_cast(IrPrint *irp, IrInstructionCanImplicitCas | ... | @@ -886,8 +886,12 @@ static void ir_print_can_implicit_cast(IrPrint *irp, IrInstructionCanImplicitCas |
| 886 | } | 886 | } |
| 887 | 887 | ||
| 888 | static void ir_print_ptr_type_of(IrPrint *irp, IrInstructionPtrTypeOf *instruction) { | 888 | static void ir_print_ptr_type_of(IrPrint *irp, IrInstructionPtrTypeOf *instruction) { |
| 889 | fprintf(irp->f, "&align "); | 889 | fprintf(irp->f, "&"); |
| 890 | ir_print_other_instruction(irp, instruction->align_value); | 890 | if (instruction->align_value != nullptr) { |
| 891 | fprintf(irp->f, "align("); | ||
| 892 | ir_print_other_instruction(irp, instruction->align_value); | ||
| 893 | fprintf(irp->f, ")"); | ||
| 894 | } | ||
| 891 | const char *const_str = instruction->is_const ? "const " : ""; | 895 | const char *const_str = instruction->is_const ? "const " : ""; |
| 892 | const char *volatile_str = instruction->is_volatile ? "volatile " : ""; | 896 | const char *volatile_str = instruction->is_volatile ? "volatile " : ""; |
| 893 | fprintf(irp->f, ":%" PRIu32 ":%" PRIu32 " %s%s", instruction->bit_offset_start, instruction->bit_offset_end, | 897 | fprintf(irp->f, ":%" PRIu32 ":%" PRIu32 " %s%s", instruction->bit_offset_start, instruction->bit_offset_end, |
std/base64.zig+1-1| ... | @@ -193,7 +193,7 @@ pub const Base64DecoderWithIgnore = struct { | ... | @@ -193,7 +193,7 @@ pub const Base64DecoderWithIgnore = struct { |
| 193 | /// Decoding more data than can fit in dest results in error.OutputTooSmall. See also ::calcSizeUpperBound. | 193 | /// Decoding more data than can fit in dest results in error.OutputTooSmall. See also ::calcSizeUpperBound. |
| 194 | /// Returns the number of bytes writen to dest. | 194 | /// Returns the number of bytes writen to dest. |
| 195 | pub fn decode(decoder_with_ignore: &const Base64DecoderWithIgnore, dest: []u8, source: []const u8) -> %usize { | 195 | pub fn decode(decoder_with_ignore: &const Base64DecoderWithIgnore, dest: []u8, source: []const u8) -> %usize { |
| 196 | const decoder = &const decoder_with_ignore.decoder; | 196 | const decoder = &decoder_with_ignore.decoder; |
| 197 | 197 | ||
| 198 | var src_cursor: usize = 0; | 198 | var src_cursor: usize = 0; |
| 199 | var dest_cursor: usize = 0; | 199 | var dest_cursor: usize = 0; |
test/behavior.zig+1| ... | @@ -7,6 +7,7 @@ comptime { | ... | @@ -7,6 +7,7 @@ comptime { |
| 7 | _ = @import("cases/bitcast.zig"); | 7 | _ = @import("cases/bitcast.zig"); |
| 8 | _ = @import("cases/bool.zig"); | 8 | _ = @import("cases/bool.zig"); |
| 9 | _ = @import("cases/bugs/394.zig"); | 9 | _ = @import("cases/bugs/394.zig"); |
| 10 | _ = @import("cases/bugs/655.zig"); | ||
| 10 | _ = @import("cases/cast.zig"); | 11 | _ = @import("cases/cast.zig"); |
| 11 | _ = @import("cases/const_slice_child.zig"); | 12 | _ = @import("cases/const_slice_child.zig"); |
| 12 | _ = @import("cases/defer.zig"); | 13 | _ = @import("cases/defer.zig"); |
test/cases/bugs/655.zig created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const other_file = @import("655_other_file.zig"); | ||
| 3 | |||
| 4 | test "function with &const parameter with type dereferenced by namespace" { | ||
| 5 | const x: other_file.Integer = 1234; | ||
| 6 | comptime std.debug.assert(@typeOf(&x) == &const other_file.Integer); | ||
| 7 | foo(x); | ||
| 8 | } | ||
| 9 | |||
| 10 | fn foo(x: &const other_file.Integer) { | ||
| 11 | std.debug.assert(*x == 1234); | ||
| 12 | } | ||
test/cases/bugs/655_other_file.zig created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | pub const Integer = u32; | ||
test/cases/misc.zig+1-1| ... | @@ -504,7 +504,7 @@ test "@typeName" { | ... | @@ -504,7 +504,7 @@ test "@typeName" { |
| 504 | 504 | ||
| 505 | test "volatile load and store" { | 505 | test "volatile load and store" { |
| 506 | var number: i32 = 1234; | 506 | var number: i32 = 1234; |
| 507 | const ptr = &volatile number; | 507 | const ptr = (&volatile i32)(&number); |
| 508 | *ptr += 1; | 508 | *ptr += 1; |
| 509 | assert(*ptr == 1235); | 509 | assert(*ptr == 1235); |
| 510 | } | 510 | } |