ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.13k stars 2.49k forks source link

cImport causes "identifier cannot be empty" when accessing an unnamed field in a struct with a bitfield #16302

Open pfgithub opened 1 year ago

pfgithub commented 1 year ago

Zig Version

0.11.0-dev.3905+309aacfc8

Steps to Reproduce and Observed Behavior

// a.c
typedef struct {
    char fmt : 8;
    union {
        char maxLevel;
    };
} C3D_Tex;

char C3D_TexGetImagePtr(C3D_Tex tex) {
    return tex.maxLevel;
}
zig translate-c a.c > a.zig
zig ast-check a.zig
a.zig:58:16: error: identifier cannot be empty
    return tex.@"".maxLevel;

Expected Behavior

It should not block compilation, for example by accessing .unnamed_0 instead or generating a @compileError

pfgithub commented 3 months ago

I just hit this again. This should maybe fix it:

diff --git a/src/translate_c.zig b/src/translate_c.zig
index 148b73955b..3806c5d174 100644
--- a/src/translate_c.zig
+++ b/src/translate_c.zig
@@ -3323,7 +3323,11 @@ fn transMemberExpr(c: *Context, scope: *Scope, stmt: *const clang.MemberExpr, re
             }
         }
         const decl = @as(*const clang.NamedDecl, @ptrCast(member_decl));
-        break :blk try c.str(decl.getName_bytes_begin());
+        const res = try c.str(decl.getName_bytes_begin());
+        if(res.len == 0) {
+            break :blk "anonymous";
+        }
+        break :blk res;
     };

     var node = try Tag.field_access.create(c.arena, .{ .lhs = container_node, .field_name = name });
but I still can't build zig to test it ``` error: sub-compilation of libcxx failed :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' error: sub-compilation of libcxxabi failed :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' :1:1: note: unable to create target: 'Unable to find target for this triple (no targets are registered)' ```
Vexu commented 2 months ago

The correct fix is to check if the struct was demoted to opaque and fail the function.

diff --git a/src/translate_c.zig b/src/translate_c.zig
index 8778310751..b027399c59 100644
--- a/src/translate_c.zig
+++ b/src/translate_c.zig
@@ -3305,6 +3305,8 @@ fn transStmtExpr(c: *Context, scope: *Scope, stmt: *const clang.StmtExpr, used:
 }

 fn transMemberExpr(c: *Context, scope: *Scope, stmt: *const clang.MemberExpr, result_used: ResultUsed) TransError!Node {
+    if (qualTypeWasDemotedToOpaque(c, stmt.getType()))
+        return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "cannot get member of struct demoted to opaque", .{});
     var container_node = try transExpr(c, scope, stmt.getBase(), .used);
     if (stmt.isArrow()) {
         container_node = try Tag.deref.create(c.arena, container_node);