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
793793pub extern fn ZigClangEnumDecl_enumerator_iterator_next(ZigClangEnumDecl_enumerator_iterator) ZigClangEnumDecl_enumerator_iterator;
794794pub extern fn ZigClangEnumDecl_enumerator_iterator_deref(ZigClangEnumDecl_enumerator_iterator) *const ZigClangEnumConstantDecl;
795795pub 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;
797798pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool;
798799pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) *const struct_ZigClangTypedefNameDecl;
799800pub 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
382382}
383383
384384fn declVisitorNamesOnly(c: *Context, decl: *const ZigClangDecl) Error!void {
385 const decl_name = try c.str(ZigClangDecl_getName_bytes_begin(decl));
386 _ = try c.global_names.put(decl_name, {});
385 if (ZigClangDecl_castToNamedDecl(decl)) |named_decl| {
386 const decl_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(named_decl));
387 _ = try c.global_names.put(decl_name, {});
388 }
387389}
388390
389391fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
......@@ -403,6 +405,9 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
403405 .Var => {
404406 return visitVarDecl(c, @ptrCast(*const ZigClangVarDecl, decl));
405407 },
408 .Empty => {
409 // Do nothing
410 },
406411 else => {
407412 const decl_name = try c.str(ZigClangDecl_getDeclKindName(decl));
408413 try emitWarning(c, ZigClangDecl_getLocation(decl), "ignoring {} declaration", .{decl_name});
......@@ -411,7 +416,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
411416}
412417
413418fn 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)));
415420 if (c.global_scope.sym_table.contains(fn_name))
416421 return; // Avoid processing this decl twice
417422
......@@ -521,7 +526,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
521526}
522527
523528fn 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)));
525530 if (c.global_scope.sym_table.contains(var_name))
526531 return; // Avoid processing this decl twice
527532 const rp = makeRestorePoint(c);
......@@ -648,7 +653,7 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l
648653 return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice
649654 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
653658 // TODO https://github.com/ziglang/zig/issues/3756
654659 // TODO https://github.com/ziglang/zig/issues/1802
......@@ -708,7 +713,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
708713 return try transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice
709714 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)));
712717 var is_unnamed = false;
713718 // Record declarations such as `struct {...} x` have no name but they're not
714719 // anonymous hence here isAnonymousStructOrUnion is not needed
......@@ -777,7 +782,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
777782 }
778783
779784 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)));
781786 if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) {
782787 raw_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()});
783788 is_anon = true;
......@@ -830,7 +835,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
830835 const rp = makeRestorePoint(c);
831836 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)));
834839 var is_unnamed = false;
835840 if (bare_name.len == 0) {
836841 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
899904 while (ZigClangEnumDecl_enumerator_iterator_neq(it, end_it)) : (it = ZigClangEnumDecl_enumerator_iterator_next(it)) {
900905 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
904909 const field_name = if (!is_unnamed and mem.startsWith(u8, enum_val_name, bare_name))
905910 enum_val_name[bare_name.len..]
......@@ -1303,8 +1308,8 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
13031308 else
13041309 try appendToken(c, .Keyword_threadlocal, "threadlocal");
13051310 const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
1306 const name = try c.str(ZigClangDecl_getName_bytes_begin(
1307 @ptrCast(*const ZigClangDecl, var_decl),
1311 const name = try c.str(ZigClangNamedDecl_getName_bytes_begin(
1312 @ptrCast(*const ZigClangNamedDecl, var_decl),
13081313 ));
13091314 const mangled_name = try block_scope.makeMangledName(c, name);
13101315 const node = try transCreateNodeVarDecl(c, false, ZigClangQualType_isConstQualified(qual_type), mangled_name);
......@@ -1347,7 +1352,7 @@ fn transDeclRefExpr(
13471352 lrvalue: LRValue,
13481353) TransError!*ast.Node {
13491354 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)));
13511356 const mangled_name = scope.getAlias(name);
13521357 return transCreateNodeIdentifier(rp.c, mangled_name);
13531358}
......@@ -1938,7 +1943,7 @@ fn transInitListExprRecord(
19381943 // .field_name = expr
19391944 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)));
19421947 if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) {
19431948 const name = rp.c.decl_table.get(@ptrToInt(ZigClangFieldDecl_getCanonicalDecl(field_decl))).?;
19441949 raw_name = try mem.dupe(rp.c.a(), u8, name.value);
......@@ -2563,8 +2568,8 @@ fn transMemberExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangMemberE
25632568 break :blk try mem.dupe(rp.c.a(), u8, name.value);
25642569 }
25652570 }
2566 const decl = @ptrCast(*const ZigClangDecl, member_decl);
2567 break :blk try rp.c.str(ZigClangDecl_getName_bytes_begin(decl));
2571 const decl = @ptrCast(*const ZigClangNamedDecl, member_decl);
2572 break :blk try rp.c.str(ZigClangNamedDecl_getName_bytes_begin(decl));
25682573 };
25692574
25702575 const node = try transCreateNodeFieldAccess(rp.c, container_node, name);
......@@ -3326,7 +3331,7 @@ fn qualTypeIntBitWidth(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigCl
33263331 .Typedef => {
33273332 const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);
33283333 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
33313336 if (mem.eql(u8, type_name, "uint8_t") or mem.eql(u8, type_name, "int8_t")) {
33323337 return 8;
......@@ -4487,7 +4492,7 @@ fn finishTransFnProto(
44874492 const param_name_tok: ?ast.TokenIndex = blk: {
44884493 if (fn_decl) |decl| {
44894494 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)));
44914496 if (param_name.len < 1)
44924497 break :blk null;
44934498
src/zig_clang.cpp+9-4
......@@ -1649,10 +1649,15 @@ bool ZigClangRecordDecl_isAnonymousStructOrUnion(const ZigClangRecordDecl *recor
16491649 return reinterpret_cast<const clang::RecordDecl*>(record_decl)->isAnonymousStructOrUnion();
16501650}
16511651
1652const char *ZigClangDecl_getName_bytes_begin(const ZigClangDecl *zig_decl) {
1653 const clang::Decl *decl = reinterpret_cast<const clang::Decl *>(zig_decl);
1654 const clang::NamedDecl *named_decl = static_cast<const clang::NamedDecl *>(decl);
1655 return (const char *)named_decl->getName().bytes_begin();
1652const ZigClangNamedDecl* ZigClangDecl_castToNamedDecl(const ZigClangDecl *self) {
1653 auto casted = reinterpret_cast<const clang::Decl *>(self);
1654 auto cast = clang::dyn_cast<const clang::NamedDecl>(casted);
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();
16561661}
16571662
16581663ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *self) {
src/zig_clang.h+2-1
......@@ -909,7 +909,8 @@ ZIG_EXTERN_C bool ZigClangEnumDecl_enumerator_iterator_neq(
909909 struct ZigClangEnumDecl_enumerator_iterator a,
910910 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);
913914ZIG_EXTERN_C enum ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *decl);
914915ZIG_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");
22const builtin = @import("builtin");
33
44pub fn addCases(cases: *tests.TranslateCContext) void {
5 cases.add("empty declaration",
6 \\;
7 , &[_][]const u8{""});
8
59 cases.add("#define hex literal with capital X",
610 \\#define VAL 0XF00D
711 , &[_][]const u8{