Commit 35c694d614

Evan Haas <evan@lagerdata.com>
2021-05-18 00:57:54
translate-c: Demote initialization of opaque types
This fixes a segfault in translate-c that would previously occur when initializing structs with unnamed bitfields, due to a failed assertion in `transInitListExprRecord`. Unnamed bitfields do not have initializers, so `transInitListExprRecord` erroneously assumes that `init_count` equals the number of fields in the record. Since attempting to initialize an opaque type is a syntax error in Zig, we can just demote any attempts to initialize them.
1 parent 0dd0c96
Changed files (2)
src/translate_c.zig
@@ -2445,6 +2445,10 @@ fn transInitListExpr(
     var qual_type = qt.getTypePtr();
     const source_loc = @ptrCast(*const clang.Expr, expr).getBeginLoc();
 
+    if (qualTypeWasDemotedToOpaque(c, qt)) {
+        return fail(c, error.UnsupportedTranslation, source_loc, "Cannot initialize opaque type", .{});
+    }
+
     if (qual_type.isRecordType()) {
         return maybeSuppressResult(c, scope, used, try transInitListExprRecord(
             c,
test/translate_c.zig
@@ -3513,4 +3513,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
        \\    asm (".globl func\n\t.type func, @function\n\tfunc:\n\t.cfi_startproc\n\tmovl $42, %eax\n\tret\n\t.cfi_endproc");
        \\}
     });
+
+    cases.add("Demote function that initializes opaque struct",
+        \\struct my_struct {
+        \\    unsigned a: 15;
+        \\    unsigned: 2;
+        \\    unsigned b: 15;
+        \\};
+        \\void initialize(void) {
+        \\    struct my_struct S = {.a = 1, .b = 2};
+        \\}
+    , &[_][]const u8{
+        \\warning: Cannot initialize opaque type
+        ,
+        \\warning: unable to translate function, demoted to extern
+        \\pub extern fn initialize() void;
+    });
 }