authorgravatar for evan@lagerdata.comEvan Haas <evan@lagerdata.com> 2021-05-17 15:57:54-07:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-05-18 09:04:19+03:00
log35c694d614c8687ffa99ac187e60d831f9d7f29d
tree3d81a351ae9a1cca3f6e783dd4ea40df968c0faa
parent0dd0c9620d66afcfabaf3dcb21b636530fd0ccba

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.

2 files changed, 20 insertions(+), 0 deletions(-)

src/translate_c.zig+4
......@@ -2445,6 +2445,10 @@ fn transInitListExpr(
24452445 var qual_type = qt.getTypePtr();
24462446 const source_loc = @ptrCast(*const clang.Expr, expr).getBeginLoc();
24472447
2448 if (qualTypeWasDemotedToOpaque(c, qt)) {
2449 return fail(c, error.UnsupportedTranslation, source_loc, "Cannot initialize opaque type", .{});
2450 }
2451
24482452 if (qual_type.isRecordType()) {
24492453 return maybeSuppressResult(c, scope, used, try transInitListExprRecord(
24502454 c,
test/translate_c.zig+16
......@@ -3513,4 +3513,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
35133513 \\ asm (".globl func\n\t.type func, @function\n\tfunc:\n\t.cfi_startproc\n\tmovl $42, %eax\n\tret\n\t.cfi_endproc");
35143514 \\}
35153515 });
3516
3517 cases.add("Demote function that initializes opaque struct",
3518 \\struct my_struct {
3519 \\ unsigned a: 15;
3520 \\ unsigned: 2;
3521 \\ unsigned b: 15;
3522 \\};
3523 \\void initialize(void) {
3524 \\ struct my_struct S = {.a = 1, .b = 2};
3525 \\}
3526 , &[_][]const u8{
3527 \\warning: Cannot initialize opaque type
3528 ,
3529 \\warning: unable to translate function, demoted to extern
3530 \\pub extern fn initialize() void;
3531 });
35163532}