| author | |
| committer | |
| log | 49cb1683ff1f87c3a9af0b564de0aa7a5b4daf7d |
| tree | 33a4ef48eb21d006ffe3897f37dd9178d44bef57 |
| parent | bdf5739c0a982d24a722b625a660a15bef617ce9 |
This prevents incorrectly casting an ElaboratedType to ArrayType
if the flexible field is a typedef'ed zero-length array
Fixes #168382 files changed, 20 insertions(+), 1 deletions(-)
src/translate_c.zig+2-1| ... | @@ -965,6 +965,7 @@ fn buildFlexibleArrayFn( | ... | @@ -965,6 +965,7 @@ fn buildFlexibleArrayFn( |
| 965 | field_decl: *const clang.FieldDecl, | 965 | field_decl: *const clang.FieldDecl, |
| 966 | ) TypeError!Node { | 966 | ) TypeError!Node { |
| 967 | const field_qt = field_decl.getType(); | 967 | const field_qt = field_decl.getType(); |
| 968 | const field_qt_canon = qualTypeCanon(field_qt); | ||
| 968 | 969 | ||
| 969 | const u8_type = try Tag.type.create(c.arena, "u8"); | 970 | const u8_type = try Tag.type.create(c.arena, "u8"); |
| 970 | const self_param_name = "self"; | 971 | const self_param_name = "self"; |
| ... | @@ -979,7 +980,7 @@ fn buildFlexibleArrayFn( | ... | @@ -979,7 +980,7 @@ fn buildFlexibleArrayFn( |
| 979 | .is_noalias = false, | 980 | .is_noalias = false, |
| 980 | }; | 981 | }; |
| 981 | 982 | ||
| 982 | const array_type = @as(*const clang.ArrayType, @ptrCast(field_qt.getTypePtr())); | 983 | const array_type = @as(*const clang.ArrayType, @ptrCast(field_qt_canon)); |
| 983 | const element_qt = array_type.getElementType(); | 984 | const element_qt = array_type.getElementType(); |
| 984 | const element_type = try transQualType(c, scope, element_qt, field_decl.getLocation()); | 985 | const element_type = try transQualType(c, scope, element_qt, field_decl.getLocation()); |
| 985 | 986 |
test/run_translated_c.zig+18| ... | @@ -1554,6 +1554,24 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { | ... | @@ -1554,6 +1554,24 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { |
| 1554 | \\} | 1554 | \\} |
| 1555 | , ""); | 1555 | , ""); |
| 1556 | 1556 | ||
| 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 | |||
| 1557 | cases.add("enum with value that fits in c_uint but not c_int, issue #8003", | 1575 | cases.add("enum with value that fits in c_uint but not c_int, issue #8003", |
| 1558 | \\#include <stdlib.h> | 1576 | \\#include <stdlib.h> |
| 1559 | \\enum my_enum { | 1577 | \\enum my_enum { |