authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-11 18:06:54+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-11 15:51:10-05:00
log34ae1d9aa8aa7b5ad7371a7df3e3ffa5a54df1d4
tree6628ad9e0286f050a87ba30a9f88c87e9d68db29
parent0827e298ede4248ae60a13e931c500104ef591e8

Fix unsafe cast in translate_c

* Handle EmptyDecls to clean up the generated code Closes #4143

5 files changed, 39 insertions(+), 23 deletions(-)

src-self-hosted/clang.zig+2-1
...@@ -793,7 +793,8 @@ pub extern fn ZigClangEnumDecl_enumerator_end(*const ZigClangEnumDecl) ZigClangE...@@ -793,7 +793,8 @@ pub extern fn ZigClangEnumDecl_enumerator_end(*const ZigClangEnumDecl) ZigClangE
793pub extern fn ZigClangEnumDecl_enumerator_iterator_next(ZigClangEnumDecl_enumerator_iterator) ZigClangEnumDecl_enumerator_iterator;793pub extern fn ZigClangEnumDecl_enumerator_iterator_next(ZigClangEnumDecl_enumerator_iterator) ZigClangEnumDecl_enumerator_iterator;
794pub extern fn ZigClangEnumDecl_enumerator_iterator_deref(ZigClangEnumDecl_enumerator_iterator) *const ZigClangEnumConstantDecl;794pub extern fn ZigClangEnumDecl_enumerator_iterator_deref(ZigClangEnumDecl_enumerator_iterator) *const ZigClangEnumConstantDecl;
795pub extern fn ZigClangEnumDecl_enumerator_iterator_neq(ZigClangEnumDecl_enumerator_iterator, ZigClangEnumDecl_enumerator_iterator) bool;795pub extern fn ZigClangEnumDecl_enumerator_iterator_neq(ZigClangEnumDecl_enumerator_iterator, ZigClangEnumDecl_enumerator_iterator) bool;
796pub extern fn ZigClangDecl_getName_bytes_begin(decl: ?*const struct_ZigClangDecl) [*:0]const u8;796pub extern fn ZigClangDecl_castToNamedDecl(decl: *const struct_ZigClangDecl) ?*const ZigClangNamedDecl;
797pub extern fn ZigClangNamedDecl_getName_bytes_begin(decl: ?*const struct_ZigClangNamedDecl) [*:0]const u8;
797pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool;798pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool;
798pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) *const struct_ZigClangTypedefNameDecl;799pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) *const struct_ZigClangTypedefNameDecl;
799pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(self: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType;800pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(self: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType;
src-self-hosted/translate_c.zig+22-17
...@@ -382,8 +382,10 @@ fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) callconv(.C) bool...@@ -382,8 +382,10 @@ fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) callconv(.C) bool
382}382}
383383
384fn declVisitorNamesOnly(c: *Context, decl: *const ZigClangDecl) Error!void {384fn declVisitorNamesOnly(c: *Context, decl: *const ZigClangDecl) Error!void {
385 const decl_name = try c.str(ZigClangDecl_getName_bytes_begin(decl));385 if (ZigClangDecl_castToNamedDecl(decl)) |named_decl| {
386 _ = try c.global_names.put(decl_name, {});386 const decl_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(named_decl));
387 _ = try c.global_names.put(decl_name, {});
388 }
387}389}
388390
389fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {391fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
...@@ -403,6 +405,9 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {...@@ -403,6 +405,9 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
403 .Var => {405 .Var => {
404 return visitVarDecl(c, @ptrCast(*const ZigClangVarDecl, decl));406 return visitVarDecl(c, @ptrCast(*const ZigClangVarDecl, decl));
405 },407 },
408 .Empty => {
409 // Do nothing
410 },
406 else => {411 else => {
407 const decl_name = try c.str(ZigClangDecl_getDeclKindName(decl));412 const decl_name = try c.str(ZigClangDecl_getDeclKindName(decl));
408 try emitWarning(c, ZigClangDecl_getLocation(decl), "ignoring {} declaration", .{decl_name});413 try emitWarning(c, ZigClangDecl_getLocation(decl), "ignoring {} declaration", .{decl_name});
...@@ -411,7 +416,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {...@@ -411,7 +416,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
411}416}
412417
413fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {418fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
414 const fn_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, fn_decl)));419 const fn_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, fn_decl)));
415 if (c.global_scope.sym_table.contains(fn_name))420 if (c.global_scope.sym_table.contains(fn_name))
416 return; // Avoid processing this decl twice421 return; // Avoid processing this decl twice
417422
...@@ -521,7 +526,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {...@@ -521,7 +526,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
521}526}
522527
523fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {528fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
524 const var_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, var_decl)));529 const var_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, var_decl)));
525 if (c.global_scope.sym_table.contains(var_name))530 if (c.global_scope.sym_table.contains(var_name))
526 return; // Avoid processing this decl twice531 return; // Avoid processing this decl twice
527 const rp = makeRestorePoint(c);532 const rp = makeRestorePoint(c);
...@@ -648,7 +653,7 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l...@@ -648,7 +653,7 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l
648 return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice653 return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice
649 const rp = makeRestorePoint(c);654 const rp = makeRestorePoint(c);
650655
651 const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));656 const typedef_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, typedef_decl)));
652657
653 // TODO https://github.com/ziglang/zig/issues/3756658 // TODO https://github.com/ziglang/zig/issues/3756
654 // TODO https://github.com/ziglang/zig/issues/1802659 // TODO https://github.com/ziglang/zig/issues/1802
...@@ -708,7 +713,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*...@@ -708,7 +713,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
708 return try transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice713 return try transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice
709 const record_loc = ZigClangRecordDecl_getLocation(record_decl);714 const record_loc = ZigClangRecordDecl_getLocation(record_decl);
710715
711 var bare_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, record_decl)));716 var bare_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, record_decl)));
712 var is_unnamed = false;717 var is_unnamed = false;
713 // Record declarations such as `struct {...} x` have no name but they're not718 // Record declarations such as `struct {...} x` have no name but they're not
714 // anonymous hence here isAnonymousStructOrUnion is not needed719 // anonymous hence here isAnonymousStructOrUnion is not needed
...@@ -777,7 +782,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*...@@ -777,7 +782,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
777 }782 }
778783
779 var is_anon = false;784 var is_anon = false;
780 var raw_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl)));785 var raw_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl)));
781 if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) {786 if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) {
782 raw_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()});787 raw_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()});
783 is_anon = true;788 is_anon = true;
...@@ -830,7 +835,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No...@@ -830,7 +835,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
830 const rp = makeRestorePoint(c);835 const rp = makeRestorePoint(c);
831 const enum_loc = ZigClangEnumDecl_getLocation(enum_decl);836 const enum_loc = ZigClangEnumDecl_getLocation(enum_decl);
832837
833 var bare_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, enum_decl)));838 var bare_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, enum_decl)));
834 var is_unnamed = false;839 var is_unnamed = false;
835 if (bare_name.len == 0) {840 if (bare_name.len == 0) {
836 bare_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()});841 bare_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()});
...@@ -899,7 +904,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No...@@ -899,7 +904,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
899 while (ZigClangEnumDecl_enumerator_iterator_neq(it, end_it)) : (it = ZigClangEnumDecl_enumerator_iterator_next(it)) {904 while (ZigClangEnumDecl_enumerator_iterator_neq(it, end_it)) : (it = ZigClangEnumDecl_enumerator_iterator_next(it)) {
900 const enum_const = ZigClangEnumDecl_enumerator_iterator_deref(it);905 const enum_const = ZigClangEnumDecl_enumerator_iterator_deref(it);
901906
902 const enum_val_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, enum_const)));907 const enum_val_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, enum_const)));
903908
904 const field_name = if (!is_unnamed and mem.startsWith(u8, enum_val_name, bare_name))909 const field_name = if (!is_unnamed and mem.startsWith(u8, enum_val_name, bare_name))
905 enum_val_name[bare_name.len..]910 enum_val_name[bare_name.len..]
...@@ -1303,8 +1308,8 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)...@@ -1303,8 +1308,8 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
1303 else1308 else
1304 try appendToken(c, .Keyword_threadlocal, "threadlocal");1309 try appendToken(c, .Keyword_threadlocal, "threadlocal");
1305 const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);1310 const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
1306 const name = try c.str(ZigClangDecl_getName_bytes_begin(1311 const name = try c.str(ZigClangNamedDecl_getName_bytes_begin(
1307 @ptrCast(*const ZigClangDecl, var_decl),1312 @ptrCast(*const ZigClangNamedDecl, var_decl),
1308 ));1313 ));
1309 const mangled_name = try block_scope.makeMangledName(c, name);1314 const mangled_name = try block_scope.makeMangledName(c, name);
1310 const node = try transCreateNodeVarDecl(c, false, ZigClangQualType_isConstQualified(qual_type), mangled_name);1315 const node = try transCreateNodeVarDecl(c, false, ZigClangQualType_isConstQualified(qual_type), mangled_name);
...@@ -1347,7 +1352,7 @@ fn transDeclRefExpr(...@@ -1347,7 +1352,7 @@ fn transDeclRefExpr(
1347 lrvalue: LRValue,1352 lrvalue: LRValue,
1348) TransError!*ast.Node {1353) TransError!*ast.Node {
1349 const value_decl = ZigClangDeclRefExpr_getDecl(expr);1354 const value_decl = ZigClangDeclRefExpr_getDecl(expr);
1350 const name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, value_decl)));1355 const name = try rp.c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, value_decl)));
1351 const mangled_name = scope.getAlias(name);1356 const mangled_name = scope.getAlias(name);
1352 return transCreateNodeIdentifier(rp.c, mangled_name);1357 return transCreateNodeIdentifier(rp.c, mangled_name);
1353}1358}
...@@ -1938,7 +1943,7 @@ fn transInitListExprRecord(...@@ -1938,7 +1943,7 @@ fn transInitListExprRecord(
1938 // .field_name = expr1943 // .field_name = expr
1939 const period_tok = try appendToken(rp.c, .Period, ".");1944 const period_tok = try appendToken(rp.c, .Period, ".");
19401945
1941 var raw_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl)));1946 var raw_name = try rp.c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl)));
1942 if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) {1947 if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) {
1943 const name = rp.c.decl_table.get(@ptrToInt(ZigClangFieldDecl_getCanonicalDecl(field_decl))).?;1948 const name = rp.c.decl_table.get(@ptrToInt(ZigClangFieldDecl_getCanonicalDecl(field_decl))).?;
1944 raw_name = try mem.dupe(rp.c.a(), u8, name.value);1949 raw_name = try mem.dupe(rp.c.a(), u8, name.value);
...@@ -2563,8 +2568,8 @@ fn transMemberExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangMemberE...@@ -2563,8 +2568,8 @@ fn transMemberExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangMemberE
2563 break :blk try mem.dupe(rp.c.a(), u8, name.value);2568 break :blk try mem.dupe(rp.c.a(), u8, name.value);
2564 }2569 }
2565 }2570 }
2566 const decl = @ptrCast(*const ZigClangDecl, member_decl);2571 const decl = @ptrCast(*const ZigClangNamedDecl, member_decl);
2567 break :blk try rp.c.str(ZigClangDecl_getName_bytes_begin(decl));2572 break :blk try rp.c.str(ZigClangNamedDecl_getName_bytes_begin(decl));
2568 };2573 };
25692574
2570 const node = try transCreateNodeFieldAccess(rp.c, container_node, name);2575 const node = try transCreateNodeFieldAccess(rp.c, container_node, name);
...@@ -3326,7 +3331,7 @@ fn qualTypeIntBitWidth(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigCl...@@ -3326,7 +3331,7 @@ fn qualTypeIntBitWidth(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigCl
3326 .Typedef => {3331 .Typedef => {
3327 const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);3332 const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);
3328 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);3333 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
3329 const type_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));3334 const type_name = try rp.c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, typedef_decl)));
33303335
3331 if (mem.eql(u8, type_name, "uint8_t") or mem.eql(u8, type_name, "int8_t")) {3336 if (mem.eql(u8, type_name, "uint8_t") or mem.eql(u8, type_name, "int8_t")) {
3332 return 8;3337 return 8;
...@@ -4487,7 +4492,7 @@ fn finishTransFnProto(...@@ -4487,7 +4492,7 @@ fn finishTransFnProto(
4487 const param_name_tok: ?ast.TokenIndex = blk: {4492 const param_name_tok: ?ast.TokenIndex = blk: {
4488 if (fn_decl) |decl| {4493 if (fn_decl) |decl| {
4489 const param = ZigClangFunctionDecl_getParamDecl(decl, @intCast(c_uint, i));4494 const param = ZigClangFunctionDecl_getParamDecl(decl, @intCast(c_uint, i));
4490 const param_name: []const u8 = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, param)));4495 const param_name: []const u8 = try rp.c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, param)));
4491 if (param_name.len < 1)4496 if (param_name.len < 1)
4492 break :blk null;4497 break :blk null;
44934498
src/zig_clang.cpp+9-4
...@@ -1649,10 +1649,15 @@ bool ZigClangRecordDecl_isAnonymousStructOrUnion(const ZigClangRecordDecl *recor...@@ -1649,10 +1649,15 @@ bool ZigClangRecordDecl_isAnonymousStructOrUnion(const ZigClangRecordDecl *recor
1649 return reinterpret_cast<const clang::RecordDecl*>(record_decl)->isAnonymousStructOrUnion();1649 return reinterpret_cast<const clang::RecordDecl*>(record_decl)->isAnonymousStructOrUnion();
1650}1650}
16511651
1652const char *ZigClangDecl_getName_bytes_begin(const ZigClangDecl *zig_decl) {1652const ZigClangNamedDecl* ZigClangDecl_castToNamedDecl(const ZigClangDecl *self) {
1653 const clang::Decl *decl = reinterpret_cast<const clang::Decl *>(zig_decl);1653 auto casted = reinterpret_cast<const clang::Decl *>(self);
1654 const clang::NamedDecl *named_decl = static_cast<const clang::NamedDecl *>(decl);1654 auto cast = clang::dyn_cast<const clang::NamedDecl>(casted);
1655 return (const char *)named_decl->getName().bytes_begin();1655 return reinterpret_cast<const ZigClangNamedDecl *>(cast);
1656}
1657
1658const char *ZigClangNamedDecl_getName_bytes_begin(const ZigClangNamedDecl *self) {
1659 auto casted = reinterpret_cast<const clang::NamedDecl *>(self);
1660 return (const char *)casted->getName().bytes_begin();
1656}1661}
16571662
1658ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *self) {1663ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *self) {
src/zig_clang.h+2-1
...@@ -909,7 +909,8 @@ ZIG_EXTERN_C bool ZigClangEnumDecl_enumerator_iterator_neq(...@@ -909,7 +909,8 @@ ZIG_EXTERN_C bool ZigClangEnumDecl_enumerator_iterator_neq(
909 struct ZigClangEnumDecl_enumerator_iterator a,909 struct ZigClangEnumDecl_enumerator_iterator a,
910 struct ZigClangEnumDecl_enumerator_iterator b);910 struct ZigClangEnumDecl_enumerator_iterator b);
911911
912ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const struct ZigClangDecl *decl);912ZIG_EXTERN_C const ZigClangNamedDecl* ZigClangDecl_castToNamedDecl(const ZigClangDecl *self);
913ZIG_EXTERN_C const char *ZigClangNamedDecl_getName_bytes_begin(const struct ZigClangNamedDecl *self);
913ZIG_EXTERN_C enum ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *decl);914ZIG_EXTERN_C enum ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *decl);
914ZIG_EXTERN_C const char *ZigClangDecl_getDeclKindName(const struct ZigClangDecl *decl);915ZIG_EXTERN_C const char *ZigClangDecl_getDeclKindName(const struct ZigClangDecl *decl);
915916
test/translate_c.zig+4
...@@ -2,6 +2,10 @@ const tests = @import("tests.zig");...@@ -2,6 +2,10 @@ const tests = @import("tests.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub fn addCases(cases: *tests.TranslateCContext) void {4pub fn addCases(cases: *tests.TranslateCContext) void {
5 cases.add("empty declaration",
6 \\;
7 , &[_][]const u8{""});
8
5 cases.add("#define hex literal with capital X",9 cases.add("#define hex literal with capital X",
6 \\#define VAL 0XF00D10 \\#define VAL 0XF00D
7 , &[_][]const u8{11 , &[_][]const u8{