Commit f55fdc00fc

Andrew Kelley <superjoe30@gmail.com>
2017-12-14 03:53:52
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
1 parent 84619ab
doc/docgen.zig
@@ -42,7 +42,7 @@ const State = enum {
 
 // TODO look for code segments
 
-fn gen(in: &io.InStream, out: &const io.OutStream) {
+fn gen(in: &io.InStream, out: &io.OutStream) {
     var state = State.Start;
     while (true) {
         const byte = in.readByte() %% |err| {
src/ir.cpp
@@ -1025,7 +1025,7 @@ static IrInstruction *ir_build_ptr_type_of(IrBuilder *irb, Scope *scope, AstNode
     ptr_type_of_instruction->bit_offset_start = bit_offset_start;
     ptr_type_of_instruction->bit_offset_end = bit_offset_end;
 
-    ir_ref_instruction(align_value, irb->current_basic_block);
+    if (align_value) ir_ref_instruction(align_value, irb->current_basic_block);
     ir_ref_instruction(child_type, irb->current_basic_block);
 
     return &ptr_type_of_instruction->base;
@@ -4897,13 +4897,18 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n
     AstNode *expr_node = node->data.addr_of_expr.op_expr;
     AstNode *align_expr = node->data.addr_of_expr.align_expr;
 
-    if (align_expr == nullptr) {
+    if (align_expr == nullptr && !is_const && !is_volatile) {
         return ir_gen_node_extra(irb, expr_node, scope, make_lval_addr(is_const, is_volatile));
     }
 
-    IrInstruction *align_value = ir_gen_node(irb, align_expr, scope);
-    if (align_value == irb->codegen->invalid_instruction)
-        return align_value;
+    IrInstruction *align_value;
+    if (align_expr != nullptr) {
+        align_value = ir_gen_node(irb, align_expr, scope);
+        if (align_value == irb->codegen->invalid_instruction)
+            return align_value;
+    } else {
+        align_value = nullptr;
+    }
 
     IrInstruction *child_type = ir_gen_node(irb, expr_node, scope);
     if (child_type == irb->codegen->invalid_instruction)
@@ -15959,8 +15964,12 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_of(IrAnalyze *ira, IrInst
         return ira->codegen->builtin_types.entry_invalid;
 
     uint32_t align_bytes;
-    if (!ir_resolve_align(ira, instruction->align_value->other, &align_bytes))
-        return ira->codegen->builtin_types.entry_invalid;
+    if (instruction->align_value != nullptr) {
+        if (!ir_resolve_align(ira, instruction->align_value->other, &align_bytes))
+            return ira->codegen->builtin_types.entry_invalid;
+    } else {
+        align_bytes = get_abi_alignment(ira->codegen, child_type);
+    }
 
     ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
     out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type,
src/ir_print.cpp
@@ -886,8 +886,12 @@ static void ir_print_can_implicit_cast(IrPrint *irp, IrInstructionCanImplicitCas
 }
 
 static void ir_print_ptr_type_of(IrPrint *irp, IrInstructionPtrTypeOf *instruction) {
-    fprintf(irp->f, "&align ");
-    ir_print_other_instruction(irp, instruction->align_value);
+    fprintf(irp->f, "&");
+    if (instruction->align_value != nullptr) {
+        fprintf(irp->f, "align(");
+        ir_print_other_instruction(irp, instruction->align_value);
+        fprintf(irp->f, ")");
+    }
     const char *const_str = instruction->is_const ? "const " : "";
     const char *volatile_str = instruction->is_volatile ? "volatile " : "";
     fprintf(irp->f, ":%" PRIu32 ":%" PRIu32 " %s%s", instruction->bit_offset_start, instruction->bit_offset_end,
std/base64.zig
@@ -193,7 +193,7 @@ pub const Base64DecoderWithIgnore = struct {
     /// Decoding more data than can fit in dest results in error.OutputTooSmall. See also ::calcSizeUpperBound.
     /// Returns the number of bytes writen to dest.
     pub fn decode(decoder_with_ignore: &const Base64DecoderWithIgnore, dest: []u8, source: []const u8) -> %usize {
-        const decoder = &const decoder_with_ignore.decoder;
+        const decoder = &decoder_with_ignore.decoder;
 
         var src_cursor: usize = 0;
         var dest_cursor: usize = 0;
test/cases/bugs/655.zig
@@ -0,0 +1,12 @@
+const std = @import("std");
+const other_file = @import("655_other_file.zig");
+
+test "function with &const parameter with type dereferenced by namespace" {
+    const x: other_file.Integer = 1234;
+    comptime std.debug.assert(@typeOf(&x) == &const other_file.Integer);
+    foo(x);
+}
+
+fn foo(x: &const other_file.Integer) {
+    std.debug.assert(*x == 1234);
+}
test/cases/bugs/655_other_file.zig
@@ -0,0 +1,1 @@
+pub const Integer = u32;
test/cases/misc.zig
@@ -504,7 +504,7 @@ test "@typeName" {
 
 test "volatile load and store" {
     var number: i32 = 1234;
-    const ptr = &volatile number;
+    const ptr = (&volatile i32)(&number);
     *ptr += 1;
     assert(*ptr == 1235);
 }
test/behavior.zig
@@ -7,6 +7,7 @@ comptime {
     _ = @import("cases/bitcast.zig");
     _ = @import("cases/bool.zig");
     _ = @import("cases/bugs/394.zig");
+    _ = @import("cases/bugs/655.zig");
     _ = @import("cases/cast.zig");
     _ = @import("cases/const_slice_child.zig");
     _ = @import("cases/defer.zig");