Commit 42ea2d0d1c

Andrew Kelley <andrew@ziglang.org>
2019-06-14 21:20:52
fix `@export` for arrays and allow sections on extern variables
previously `@export` for an array would panic with a TODO message. now it will do the export. However, it uses the variable's name rather than the name passed to `@export`. Issue #2679 remains open for that problem.
1 parent 9e8db5b
Changed files (3)
src/analyze.cpp
@@ -2780,12 +2780,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
         fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);
 
         if (fn_proto->section_expr != nullptr) {
-            if (fn_table_entry->body_node == nullptr) {
-                add_node_error(g, fn_proto->section_expr,
-                    buf_sprintf("cannot set section of external function '%s'", buf_ptr(&fn_table_entry->symbol_name)));
-            } else {
-                analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name);
-            }
+            analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name);
         }
 
         if (fn_table_entry->type_entry->id == ZigTypeIdInvalid) {
@@ -3258,10 +3253,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
     }
 
     if (var_decl->section_expr != nullptr) {
-        if (var_decl->is_extern) {
-            add_node_error(g, var_decl->section_expr,
-                buf_sprintf("cannot set section of external variable '%s'", buf_ptr(var_decl->symbol)));
-        } else if (!analyze_const_string(g, tld_var->base.parent_scope, var_decl->section_expr, &tld_var->section_name)) {
+        if (!analyze_const_string(g, tld_var->base.parent_scope, var_decl->section_expr, &tld_var->section_name)) {
             tld_var->section_name = nullptr;
         }
     }
src/ir.cpp
@@ -13901,6 +13901,15 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
                 want_var_export = true;
             }
             break;
+        case ZigTypeIdArray:
+            if (!type_allowed_in_extern(ira->codegen, target->value.type->data.array.child_type)) {
+                ir_add_error(ira, target,
+                    buf_sprintf("array element type '%s' not extern-compatible",
+                        buf_ptr(&target->value.type->data.array.child_type->name)));
+            } else {
+                want_var_export = true;
+            }
+            break;
         case ZigTypeIdMetaType: {
             ZigType *type_value = target->value.data.x_type;
             switch (type_value->id) {
@@ -13968,7 +13977,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
         case ZigTypeIdInt:
         case ZigTypeIdFloat:
         case ZigTypeIdPointer:
-        case ZigTypeIdArray:
         case ZigTypeIdComptimeFloat:
         case ZigTypeIdComptimeInt:
         case ZigTypeIdUndefined:
test/compile_errors.zig
@@ -4645,16 +4645,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         "tmp.zig:1:1: note: declared here",
     );
 
-    cases.add(
-        "setting a section on an extern variable",
-        \\extern var foo: i32 linksection(".text2");
-        \\export fn entry() i32 {
-        \\    return foo;
-        \\}
-    ,
-        "tmp.zig:1:33: error: cannot set section of external variable 'foo'",
-    );
-
     cases.add(
         "setting a section on a local variable",
         \\export fn entry() i32 {
@@ -4665,16 +4655,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         "tmp.zig:2:30: error: cannot set section of local variable 'foo'",
     );
 
-    cases.add(
-        "setting a section on an extern fn",
-        \\extern fn foo() linksection(".text2") void;
-        \\export fn entry() void {
-        \\    foo();
-        \\}
-    ,
-        "tmp.zig:1:29: error: cannot set section of external function 'foo'",
-    );
-
     cases.add(
         "returning address of local variable - simple",
         \\export fn foo() *i32 {