Commit a12535f501

Jacob Young <jacobly0@users.noreply.github.com>
2022-10-09 07:48:26
cbe: fix global access
1 parent f399dd1
Changed files (3)
src
codegen
test
src/codegen/c.zig
@@ -386,6 +386,10 @@ pub const DeclGen = struct {
         val: Value,
         decl_index: Decl.Index,
     ) error{ OutOfMemory, AnalysisFail }!void {
+        if (ty.isPtrAtRuntime() and !ty.elemType2().isFnOrHasRuntimeBits()) {
+            return dg.writeCValue(writer, CValue{ .undefined_ptr = ty });
+        }
+
         if (ty.isSlice()) {
             try writer.writeByte('(');
             try dg.renderTypecast(writer, ty);
@@ -404,23 +408,15 @@ pub const DeclGen = struct {
         // them).  The analysis until now should ensure that the C function
         // pointers are compatible.  If they are not, then there is a bug
         // somewhere and we should let the C compiler tell us about it.
-        if (ty.castPtrToFn() == null) {
-            // Determine if we must pointer cast.
-            if (ty.eql(decl.ty, dg.module)) {
-                try writer.writeByte('&');
-                try dg.renderDeclName(writer, decl_index);
-                return;
-            }
-
+        const need_typecast = if (ty.castPtrToFn()) |_| false else !ty.eql(decl.ty, dg.module);
+        if (need_typecast) {
             try writer.writeAll("((");
             try dg.renderTypecast(writer, ty);
-            try writer.writeAll(")&");
-            try dg.renderDeclName(writer, decl_index);
             try writer.writeByte(')');
-            return;
         }
-
+        try writer.writeByte('&');
         try dg.renderDeclName(writer, decl_index);
+        if (need_typecast) try writer.writeByte(')');
     }
 
     // Renders a "parent" pointer by recursing to the root decl/variable
@@ -1830,7 +1826,7 @@ pub const DeclGen = struct {
 
         if (dg.module.decl_exports.get(decl_index)) |exports| {
             return writer.writeAll(exports[0].options.name);
-        } else if (decl.val.tag() == .extern_fn) {
+        } else if (decl.isExtern()) {
             return writer.writeAll(mem.sliceTo(decl.name, 0));
         } else {
             const gpa = dg.module.gpa;
@@ -1997,7 +1993,7 @@ pub fn genDecl(o: *Object) !void {
         try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align");
         try fwd_decl_writer.writeAll(";\n");
 
-        if (variable.init.isUndefDeep()) {
+        if (variable.is_extern or variable.init.isUndefDeep()) {
             return;
         }
 
test/behavior/basic.zig
@@ -383,8 +383,6 @@ fn testTakeAddressOfParameter(f: f32) !void {
 }
 
 test "pointer to void return type" {
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
-
     try testPointerToVoidReturnType();
 }
 fn testPointerToVoidReturnType() anyerror!void {
test/behavior/struct.zig
@@ -329,7 +329,6 @@ fn testReturnEmptyStructFromFn() EmptyStruct2 {
 
 test "pass slice of empty struct to fn" {
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 
     try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1);
@@ -354,8 +353,6 @@ test "self-referencing struct via array member" {
 }
 
 test "empty struct method call" {
-    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
-
     const es = EmptyStruct{};
     try expect(es.method() == 1234);
 }