authorgravatar for evan@lagerdata.comEvan Haas <evan@lagerdata.com> 2023-08-15 22:37:58-07:00
committergravatar for evan@lagerdata.comEvan Haas <evan@lagerdata.com> 2023-08-15 23:59:07-07:00
log49cb1683ff1f87c3a9af0b564de0aa7a5b4daf7d
tree33a4ef48eb21d006ffe3897f37dd9178d44bef57
parentbdf5739c0a982d24a722b625a660a15bef617ce9

translate-c: Use canonical type of field for flexible array definition

This prevents incorrectly casting an ElaboratedType to ArrayType if the flexible field is a typedef'ed zero-length array Fixes #16838

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

src/translate_c.zig+2-1
......@@ -965,6 +965,7 @@ fn buildFlexibleArrayFn(
965965 field_decl: *const clang.FieldDecl,
966966) TypeError!Node {
967967 const field_qt = field_decl.getType();
968 const field_qt_canon = qualTypeCanon(field_qt);
968969
969970 const u8_type = try Tag.type.create(c.arena, "u8");
970971 const self_param_name = "self";
......@@ -979,7 +980,7 @@ fn buildFlexibleArrayFn(
979980 .is_noalias = false,
980981 };
981982
982 const array_type = @as(*const clang.ArrayType, @ptrCast(field_qt.getTypePtr()));
983 const array_type = @as(*const clang.ArrayType, @ptrCast(field_qt_canon));
983984 const element_qt = array_type.getElementType();
984985 const element_type = try transQualType(c, scope, element_qt, field_decl.getLocation());
985986
test/run_translated_c.zig+18
......@@ -1554,6 +1554,24 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
15541554 \\}
15551555 , "");
15561556
1557 cases.add("Flexible array with typedefed flexible item, issue #16838",
1558 \\#include <stdlib.h>
1559 \\#include <assert.h>
1560 \\typedef int MARKER[0];
1561 \\typedef struct { int x; MARKER y; } Flexible;
1562 \\#define SIZE 10
1563 \\int main(void) {
1564 \\ Flexible *flex = malloc(sizeof(Flexible) + SIZE * sizeof(int));
1565 \\ for (int i = 0; i < SIZE; i++) {
1566 \\ flex->y[i] = i;
1567 \\ }
1568 \\ for (int i = 0; i < SIZE; i++) {
1569 \\ assert(flex->y[i] == i);
1570 \\ }
1571 \\ return 0;
1572 \\}
1573 , "");
1574
15571575 cases.add("enum with value that fits in c_uint but not c_int, issue #8003",
15581576 \\#include <stdlib.h>
15591577 \\enum my_enum {