authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-13 21:53:52-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-13 21:53:52-05:00
logf55fdc00fcde3cd17ed0ddb94c0997c882dbe6b9
tree911f875f15548275274e6811464850e3191b06b1
parent84619abe9f16bc030c5bdb888f47a9b49b87c2ff

fix const and volatile qualifiers being dropped sometimes

in the expression `&const a.b`, the const (and/or volatile) qualifiers would be incorrectly dropped. closes #655

8 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 {
4242
43// TODO look for code segments43// TODO look for code segments
4444
45fn gen(in: &io.InStream, out: &const io.OutStream) {45fn 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;
10271027
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);
10301030
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;
48994899
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 }
49034903
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 }
49074912
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;
1596015965
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 }
1596415973
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}
887887
888static void ir_print_ptr_type_of(IrPrint *irp, IrInstructionPtrTypeOf *instruction) {888static 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;
197197
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 @@
1const std = @import("std");
2const other_file = @import("655_other_file.zig");
3
4test "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
10fn 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 @@
1pub const Integer = u32;
test/cases/misc.zig+1-1
...@@ -504,7 +504,7 @@ test "@typeName" {...@@ -504,7 +504,7 @@ test "@typeName" {
504504
505test "volatile load and store" {505test "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}