Commit e62671f643

Vexu <git@vexu.eu>
2020-04-07 14:12:37
fix missing const on address of literal
1 parent ab05766
src/all_types.hpp
@@ -3519,8 +3519,6 @@ struct IrInstSrcRef {
     IrInstSrc base;
 
     IrInstSrc *value;
-    bool is_const;
-    bool is_volatile;
 };
 
 struct IrInstGenRef {
src/ir.cpp
@@ -3290,13 +3290,9 @@ static IrInstSrc *ir_build_import(IrBuilderSrc *irb, Scope *scope, AstNode *sour
     return &instruction->base;
 }
 
-static IrInstSrc *ir_build_ref_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value,
-        bool is_const, bool is_volatile)
-{
+static IrInstSrc *ir_build_ref_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) {
     IrInstSrcRef *instruction = ir_build_instruction<IrInstSrcRef>(irb, scope, source_node);
     instruction->value = value;
-    instruction->is_const = is_const;
-    instruction->is_volatile = is_volatile;
 
     ir_ref_instruction(value, irb->current_basic_block);
 
@@ -5938,7 +5934,7 @@ static IrInstSrc *ir_gen_symbol(IrBuilderSrc *irb, Scope *scope, AstNode *node,
     } else {
         IrInstSrc *value = ir_build_const_type(irb, scope, node, primitive_type);
         if (lval == LValPtr) {
-            return ir_build_ref_src(irb, scope, node, value, false, false);
+            return ir_build_ref_src(irb, scope, node, value);
         } else {
             return ir_expr_wrap(irb, scope, value, result_loc);
         }
@@ -7486,7 +7482,7 @@ static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value
     if (lval == LValPtr) {
         // We needed a pointer to a value, but we got a value. So we create
         // an instruction which just makes a pointer of it.
-        return ir_build_ref_src(irb, scope, value->base.source_node, value, false, false);
+        return ir_build_ref_src(irb, scope, value->base.source_node, value);
     } else if (result_loc != nullptr) {
         return ir_expr_wrap(irb, scope, value, result_loc);
     } else {
@@ -23348,7 +23344,16 @@ static IrInstGen *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstSrcRef *ref_i
     IrInstGen *value = ref_instruction->value->child;
     if (type_is_invalid(value->value->type))
         return ira->codegen->invalid_inst_gen;
-    return ir_get_ref(ira, &ref_instruction->base.base, value, ref_instruction->is_const, ref_instruction->is_volatile);
+    
+    bool is_const = false;
+    bool is_volatile = false;
+
+    ZigValue *child_value = value->value;
+    if (child_value->special == ConstValSpecialStatic) {
+        is_const = true;
+    }
+
+    return ir_get_ref(ira, &ref_instruction->base.base, value, is_const, is_volatile);
 }
 
 static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instruction,
src/ir_print.cpp
@@ -1476,9 +1476,7 @@ static void ir_print_import(IrPrintSrc *irp, IrInstSrcImport *instruction) {
 }
 
 static void ir_print_ref(IrPrintSrc *irp, IrInstSrcRef *instruction) {
-    const char *const_str = instruction->is_const ? "const " : "";
-    const char *volatile_str = instruction->is_volatile ? "volatile " : "";
-    fprintf(irp->f, "%s%sref ", const_str, volatile_str);
+    fprintf(irp->f, "ref ");
     ir_print_other_inst_src(irp, instruction->value);
 }
 
test/compile_errors.zig
@@ -2,6 +2,34 @@ const tests = @import("tests.zig");
 const std = @import("std");
 
 pub fn addCases(cases: *tests.CompileErrorContext) void {
+    cases.addTest("reference to const data",
+        \\export fn foo() void {
+        \\    var ptr = &[_]u8{0,0,0,0};
+        \\    ptr[1] = 2;
+        \\}
+        \\export fn bar() void {
+        \\    var ptr = &@as(u32, 2);
+        \\    ptr.* = 2;
+        \\}
+        \\export fn baz() void {
+        \\    var ptr = &true;
+        \\    ptr.* = false;
+        \\}
+        \\export fn qux() void {
+        \\    const S = struct{
+        \\        x: usize,
+        \\        y: usize,
+        \\    };
+        \\    var ptr = &S{.x=1,.y=2};
+        \\    ptr.x = 2;
+        \\}
+    , &[_][]const u8{
+        "tmp.zig:3:14: error: cannot assign to constant",
+        "tmp.zig:7:13: error: cannot assign to constant",
+        "tmp.zig:11:13: error: cannot assign to constant",
+        "tmp.zig:19:13: error: cannot assign to constant",
+    });
+
     cases.addTest("cast between ?T where T is not a pointer",
         \\pub const fnty1 = ?fn (i8) void;
         \\pub const fnty2 = ?fn (u64) void;