authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-08 12:07:26+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-08 12:11:37+02:00
log692a974c3edd05944d33cd579bcb355cdd7199fc
tree029600d5411dfd9c6b8b64b2c0c3df58ac3f340a
parent5aa993cd617e0ae3cabc9c626e45a748857e2f2a
signaturelock-open Commit is signed but in an unrecognized format.

translate-c reject structs with VLAs


5 files changed, 42 insertions(+), 3 deletions(-)

src-self-hosted/clang.zig+1
...@@ -812,6 +812,7 @@ pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) str...@@ -812,6 +812,7 @@ pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) str
812pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;812pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
813pub extern fn ZigClangType_isConstantArrayType(self: ?*const struct_ZigClangType) bool;813pub extern fn ZigClangType_isConstantArrayType(self: ?*const struct_ZigClangType) bool;
814pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool;814pub extern fn ZigClangType_isRecordType(self: ?*const struct_ZigClangType) bool;
815pub extern fn ZigClangType_isIncompleteOrZeroLengthArrayType(self: ?*const struct_ZigClangType, *const ZigClangASTContext) bool;
815pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool;816pub extern fn ZigClangType_isArrayType(self: ?*const struct_ZigClangType) bool;
816pub extern fn ZigClangType_isBooleanType(self: ?*const struct_ZigClangType) bool;817pub extern fn ZigClangType_isBooleanType(self: ?*const struct_ZigClangType) bool;
817pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8;818pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8;
src-self-hosted/translate_c.zig+11-3
...@@ -793,6 +793,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*...@@ -793,6 +793,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
793 while (ZigClangRecordDecl_field_iterator_neq(it, end_it)) : (it = ZigClangRecordDecl_field_iterator_next(it)) {793 while (ZigClangRecordDecl_field_iterator_neq(it, end_it)) : (it = ZigClangRecordDecl_field_iterator_next(it)) {
794 const field_decl = ZigClangRecordDecl_field_iterator_deref(it);794 const field_decl = ZigClangRecordDecl_field_iterator_deref(it);
795 const field_loc = ZigClangFieldDecl_getLocation(field_decl);795 const field_loc = ZigClangFieldDecl_getLocation(field_decl);
796 const field_qt = ZigClangFieldDecl_getType(field_decl);
796797
797 if (ZigClangFieldDecl_isBitField(field_decl)) {798 if (ZigClangFieldDecl_isBitField(field_decl)) {
798 const opaque = try transCreateNodeOpaqueType(c);799 const opaque = try transCreateNodeOpaqueType(c);
...@@ -801,6 +802,13 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*...@@ -801,6 +802,13 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
801 break :blk opaque;802 break :blk opaque;
802 }803 }
803804
805 if (ZigClangType_isIncompleteOrZeroLengthArrayType(qualTypeCanon(field_qt), c.clang_context)) {
806 const opaque = try transCreateNodeOpaqueType(c);
807 semicolon = try appendToken(c, .Semicolon, ";");
808 try emitWarning(c, field_loc, "{} demoted to opaque type - has variable length array", .{container_kind_name});
809 break :blk opaque;
810 }
811
804 var is_anon = false;812 var is_anon = false;
805 var raw_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl)));813 var raw_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl)));
806 if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) {814 if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) {
...@@ -809,7 +817,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*...@@ -809,7 +817,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
809 }817 }
810 const field_name = try appendIdentifier(c, raw_name);818 const field_name = try appendIdentifier(c, raw_name);
811 _ = try appendToken(c, .Colon, ":");819 _ = try appendToken(c, .Colon, ":");
812 const field_type = transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc) catch |err| switch (err) {820 const field_type = transQualType(rp, field_qt, field_loc) catch |err| switch (err) {
813 error.UnsupportedType => {821 error.UnsupportedType => {
814 const opaque = try transCreateNodeOpaqueType(c);822 const opaque = try transCreateNodeOpaqueType(c);
815 semicolon = try appendToken(c, .Semicolon, ";");823 semicolon = try appendToken(c, .Semicolon, ";");
...@@ -5600,7 +5608,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5600,7 +5608,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5600 },5608 },
5601 .Ampersand => {5609 .Ampersand => {
5602 op_token = try appendToken(c, .Ampersand, "&");5610 op_token = try appendToken(c, .Ampersand, "&");
5603 op_id= .BitAnd;5611 op_id = .BitAnd;
5604 },5612 },
5605 .Plus => {5613 .Plus => {
5606 op_token = try appendToken(c, .Plus, "+");5614 op_token = try appendToken(c, .Plus, "+");
...@@ -5608,7 +5616,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5608,7 +5616,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5608 },5616 },
5609 .Minus => {5617 .Minus => {
5610 op_token = try appendToken(c, .Minus, "-");5618 op_token = try appendToken(c, .Minus, "-");
5611 op_id= .Sub;5619 op_id = .Sub;
5612 },5620 },
5613 .AmpersandAmpersand => {5621 .AmpersandAmpersand => {
5614 op_token = try appendToken(c, .Keyword_and, "and");5622 op_token = try appendToken(c, .Keyword_and, "and");
src/zig_clang.cpp+20
...@@ -1881,6 +1881,26 @@ bool ZigClangType_isRecordType(const ZigClangType *self) {...@@ -1881,6 +1881,26 @@ bool ZigClangType_isRecordType(const ZigClangType *self) {
1881 return casted->isRecordType();1881 return casted->isRecordType();
1882}1882}
18831883
1884bool ZigClangType_isIncompleteOrZeroLengthArrayType(const ZigClangQualType *self,
1885 const struct ZigClangASTContext *ctx)
1886{
1887 auto casted_ctx = reinterpret_cast<const clang::ASTContext *>(ctx);
1888 auto casted = reinterpret_cast<const clang::QualType *>(self);
1889 auto casted_type = reinterpret_cast<const clang::Type *>(self);
1890 if (casted_type->isIncompleteArrayType())
1891 return true;
1892
1893 clang::QualType elem_type = *casted;
1894 while (const clang::ConstantArrayType *ArrayT = casted_ctx->getAsConstantArrayType(elem_type)) {
1895 if (ArrayT->getSize() == 0)
1896 return true;
1897
1898 elem_type = ArrayT->getElementType();
1899 }
1900
1901 return false;
1902}
1903
1884bool ZigClangType_isConstantArrayType(const ZigClangType *self) {1904bool ZigClangType_isConstantArrayType(const ZigClangType *self) {
1885 auto casted = reinterpret_cast<const clang::Type *>(self);1905 auto casted = reinterpret_cast<const clang::Type *>(self);
1886 return casted->isConstantArrayType();1906 return casted->isConstantArrayType();
src/zig_clang.h+1
...@@ -947,6 +947,7 @@ ZIG_EXTERN_C bool ZigClangType_isBooleanType(const struct ZigClangType *self);...@@ -947,6 +947,7 @@ ZIG_EXTERN_C bool ZigClangType_isBooleanType(const struct ZigClangType *self);
947ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self);947ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self);
948ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self);948ZIG_EXTERN_C bool ZigClangType_isArrayType(const struct ZigClangType *self);
949ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self);949ZIG_EXTERN_C bool ZigClangType_isRecordType(const struct ZigClangType *self);
950ZIG_EXTERN_C bool ZigClangType_isIncompleteOrZeroLengthArrayType(const ZigClangQualType *self, const struct ZigClangASTContext *ctx);
950ZIG_EXTERN_C bool ZigClangType_isConstantArrayType(const ZigClangType *self);951ZIG_EXTERN_C bool ZigClangType_isConstantArrayType(const ZigClangType *self);
951ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self);952ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self);
952ZIG_EXTERN_C const struct ZigClangArrayType *ZigClangType_getAsArrayTypeUnsafe(const struct ZigClangType *self);953ZIG_EXTERN_C const struct ZigClangArrayType *ZigClangType_getAsArrayTypeUnsafe(const struct ZigClangType *self);
test/translate_c.zig+9
...@@ -3,6 +3,15 @@ const std = @import("std");...@@ -3,6 +3,15 @@ const std = @import("std");
3const CrossTarget = std.zig.CrossTarget;3const CrossTarget = std.zig.CrossTarget;
44
5pub fn addCases(cases: *tests.TranslateCContext) void {5pub fn addCases(cases: *tests.TranslateCContext) void {
6 cases.add("structs with VLAs are rejected",
7 \\struct foo { int x; int y[]; };
8 \\struct bar { int x; int y[0]; };
9 , &[_][]const u8{
10 \\pub const struct_foo = @OpaqueType();
11 ,
12 \\pub const struct_bar = @OpaqueType();
13 });
14
6 cases.add("nested loops without blocks",15 cases.add("nested loops without blocks",
7 \\void foo() {16 \\void foo() {
8 \\ while (0) while (0) {}17 \\ while (0) while (0) {}