Commit ad9040443c

Andrew Kelley <superjoe30@gmail.com>
2017-04-22 18:54:00
new compile errors for setGlobalAlign and setGlobalSection builtins
if you try to use them on an external variable or function then you get a compile error, since the alignment/section is set externally in this case. closes #244
1 parent aafb0b9
Changed files (2)
src/ir.cpp
@@ -9887,6 +9887,10 @@ static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira,
     Tld *tld = instruction->tld;
     IrInstruction *align_value = instruction->value->other;
 
+    resolve_top_level_decl(ira->codegen, tld, true);
+    if (tld->resolution == TldResolutionInvalid)
+        return ira->codegen->builtin_types.entry_invalid;
+
     uint64_t scalar_align;
     if (!ir_resolve_usize(ira, align_value, &scalar_align))
         return ira->codegen->builtin_types.entry_invalid;
@@ -9902,11 +9906,25 @@ static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira,
         TldVar *tld_var = (TldVar *)tld;
         set_global_align_node = &tld_var->set_global_align_node;
         alignment_ptr = &tld_var->alignment;
+
+        if (tld_var->var->linkage == VarLinkageExternal) {
+            ErrorMsg *msg = ir_add_error(ira, &instruction->base,
+                    buf_sprintf("cannot set alignment of external variable '%s'", buf_ptr(&tld_var->var->name)));
+            add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here"));
+            return ira->codegen->builtin_types.entry_invalid;
+        }
     } else if (tld->id == TldIdFn) {
         TldFn *tld_fn = (TldFn *)tld;
         FnTableEntry *fn_entry = tld_fn->fn_entry;
         set_global_align_node = &fn_entry->set_global_align_node;
         alignment_ptr = &fn_entry->alignment;
+
+        if (fn_entry->def_scope == nullptr) {
+            ErrorMsg *msg = ir_add_error(ira, &instruction->base,
+                    buf_sprintf("cannot set alignment of external function '%s'", buf_ptr(&fn_entry->symbol_name)));
+            add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here"));
+            return ira->codegen->builtin_types.entry_invalid;
+        }
     } else {
         // error is caught in pass1 IR gen
         zig_unreachable();
@@ -9932,6 +9950,10 @@ static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira,
     Tld *tld = instruction->tld;
     IrInstruction *section_value = instruction->value->other;
 
+    resolve_top_level_decl(ira->codegen, tld, true);
+    if (tld->resolution == TldResolutionInvalid)
+        return ira->codegen->builtin_types.entry_invalid;
+
     Buf *section_name = ir_resolve_str(ira, section_value);
     if (!section_name)
         return ira->codegen->builtin_types.entry_invalid;
@@ -9942,11 +9964,25 @@ static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira,
         TldVar *tld_var = (TldVar *)tld;
         set_global_section_node = &tld_var->set_global_section_node;
         section_name_ptr = &tld_var->section_name;
+
+        if (tld_var->var->linkage == VarLinkageExternal) {
+            ErrorMsg *msg = ir_add_error(ira, &instruction->base,
+                    buf_sprintf("cannot set section of external variable '%s'", buf_ptr(&tld_var->var->name)));
+            add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here"));
+            return ira->codegen->builtin_types.entry_invalid;
+        }
     } else if (tld->id == TldIdFn) {
         TldFn *tld_fn = (TldFn *)tld;
         FnTableEntry *fn_entry = tld_fn->fn_entry;
         set_global_section_node = &fn_entry->set_global_section_node;
         section_name_ptr = &fn_entry->section_name;
+
+        if (fn_entry->def_scope == nullptr) {
+            ErrorMsg *msg = ir_add_error(ira, &instruction->base,
+                    buf_sprintf("cannot set section of external function '%s'", buf_ptr(&fn_entry->symbol_name)));
+            add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here"));
+            return ira->codegen->builtin_types.entry_invalid;
+        }
     } else {
         // error is caught in pass1 IR gen
         zig_unreachable();
test/compile_errors.zig
@@ -1267,12 +1267,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
     , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");
 
     cases.add("set global variable alignment to non power of 2",
-        \\const some_data: [100]u8 = {
+        \\const some_data: [100]u8 = undefined;
+        \\comptime {
         \\    @setGlobalAlign(some_data, 3);
-        \\    undefined
-        \\};
+        \\}
         \\export fn entry() -> usize { @sizeOf(@typeOf(some_data)) }
-    , ".tmp_source.zig:2:32: error: alignment value must be power of 2");
+    , ".tmp_source.zig:3:32: error: alignment value must be power of 2");
 
     cases.add("compile log",
         \\export fn foo() {
@@ -1536,4 +1536,40 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
     ,
         "error: 'main' is private",
         ".tmp_source.zig:1:1: note: declared here");
+
+    cases.add("@setGlobalAlign extern variable",
+        \\extern var foo: i32;
+        \\comptime {
+        \\    @setGlobalAlign(foo, 4);
+        \\}
+    ,
+        ".tmp_source.zig:3:5: error: cannot set alignment of external variable 'foo'",
+        ".tmp_source.zig:1:8: note: declared here");
+
+    cases.add("@setGlobalAlign extern fn",
+        \\extern fn foo();
+        \\comptime {
+        \\    @setGlobalAlign(foo, 4);
+        \\}
+    ,
+        ".tmp_source.zig:3:5: error: cannot set alignment of external function 'foo'",
+        ".tmp_source.zig:1:8: note: declared here");
+
+    cases.add("@setGlobalSection extern variable",
+        \\extern var foo: i32;
+        \\comptime {
+        \\    @setGlobalSection(foo, ".text2");
+        \\}
+    ,
+        ".tmp_source.zig:3:5: error: cannot set section of external variable 'foo'",
+        ".tmp_source.zig:1:8: note: declared here");
+
+    cases.add("@setGlobalSection extern fn",
+        \\extern fn foo();
+        \\comptime {
+        \\    @setGlobalSection(foo, ".text2");
+        \\}
+    ,
+        ".tmp_source.zig:3:5: error: cannot set section of external function 'foo'",
+        ".tmp_source.zig:1:8: note: declared here");
 }