authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-05 06:25:05-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-25 05:11:28-04:00
logda939b032e90795c25f23efa68a9a1c50397fb48
treed7c8fb65b3fdf5ec4bd6a833c426470d47a3b167
parent6f3654ad694946876e3aac971fd284230424c915

c: fix empty container warnings


1 files changed, 58 insertions(+), 36 deletions(-)

src/codegen/c.zig+58-36
...@@ -389,7 +389,7 @@ pub const DeclGen = struct {...@@ -389,7 +389,7 @@ pub const DeclGen = struct {
389 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Other);389 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Other);
390 try writer.writeAll(", ");390 try writer.writeAll(", ");
391 try writer.print("{d}", .{val.sliceLen(dg.module)});391 try writer.print("{d}", .{val.sliceLen(dg.module)});
392 try writer.writeAll("}");392 try writer.writeByte('}');
393 return;393 return;
394 }394 }
395395
...@@ -563,6 +563,7 @@ pub const DeclGen = struct {...@@ -563,6 +563,7 @@ pub const DeclGen = struct {
563 switch (ty.zigTypeTag()) {563 switch (ty.zigTypeTag()) {
564 // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)564 // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)
565 // with 'error: expected expression' (including when built with 'zig cc')565 // with 'error: expected expression' (including when built with 'zig cc')
566 .Bool => return writer.writeAll("false"),
566 .Int => {567 .Int => {
567 const c_bits = toCIntBits(ty.intInfo(dg.module.getTarget()).bits) orelse568 const c_bits = toCIntBits(ty.intInfo(dg.module.getTarget()).bits) orelse
568 return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{});569 return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
...@@ -583,14 +584,19 @@ pub const DeclGen = struct {...@@ -583,14 +584,19 @@ pub const DeclGen = struct {
583 }584 }
584 },585 },
585 .Pointer => switch (dg.module.getTarget().cpu.arch.ptrBitWidth()) {586 .Pointer => switch (dg.module.getTarget().cpu.arch.ptrBitWidth()) {
586 32 => return writer.writeAll("(void *)0xaaaaaaaa"),587 32 => return writer.writeAll("(void *)0xaaaaaaaau"),
587 64 => return writer.writeAll("(void *)0xaaaaaaaaaaaaaaaa"),588 64 => return writer.writeAll("(void *)0xaaaaaaaaaaaaaaaau"),
588 else => unreachable,589 else => unreachable,
589 },590 },
590 .Struct, .ErrorUnion => {591 .Struct, .ErrorUnion => {
591 try writer.writeByte('(');592 try writer.writeByte('(');
592 try dg.renderTypecast(writer, ty);593 try dg.renderTypecast(writer, ty);
593 return writer.writeAll("){0xaa}");594 return writer.writeAll("){0xaau}");
595 },
596 .Array => {
597 try writer.writeByte('{');
598 try dg.renderValue(writer, ty.childType(), val, location);
599 return writer.writeByte('}');
594 },600 },
595 else => {601 else => {
596 // This should lower to 0xaa bytes in safe modes, and for unsafe modes should602 // This should lower to 0xaa bytes in safe modes, and for unsafe modes should
...@@ -652,7 +658,7 @@ pub const DeclGen = struct {...@@ -652,7 +658,7 @@ pub const DeclGen = struct {
652 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, location);658 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, location);
653 try writer.writeAll(", ");659 try writer.writeAll(", ");
654 try dg.renderValue(writer, Type.usize, slice.len, location);660 try dg.renderValue(writer, Type.usize, slice.len, location);
655 try writer.writeAll("}");661 try writer.writeByte('}');
656 },662 },
657 .function => {663 .function => {
658 const func = val.castTag(.function).?.data;664 const func = val.castTag(.function).?.data;
...@@ -684,6 +690,8 @@ pub const DeclGen = struct {...@@ -684,6 +690,8 @@ pub const DeclGen = struct {
684 const ai = ty.arrayInfo();690 const ai = ty.arrayInfo();
685 if (ai.sentinel) |s| {691 if (ai.sentinel) |s| {
686 try dg.renderValue(writer, ai.elem_type, s, location);692 try dg.renderValue(writer, ai.elem_type, s, location);
693 } else {
694 try writer.writeByte('0');
687 }695 }
688 try writer.writeByte('}');696 try writer.writeByte('}');
689 },697 },
...@@ -703,12 +711,12 @@ pub const DeclGen = struct {...@@ -703,12 +711,12 @@ pub const DeclGen = struct {
703 const ai = ty.arrayInfo();711 const ai = ty.arrayInfo();
704 var index: usize = 0;712 var index: usize = 0;
705 while (index < ai.len) : (index += 1) {713 while (index < ai.len) : (index += 1) {
706 if (index != 0) try writer.writeAll(",");714 if (index != 0) try writer.writeByte(',');
707 const elem_val = try val.elemValue(dg.module, arena_allocator, index);715 const elem_val = try val.elemValue(dg.module, arena_allocator, index);
708 try dg.renderValue(writer, ai.elem_type, elem_val, .Other);716 try dg.renderValue(writer, ai.elem_type, elem_val, .Other);
709 }717 }
710 if (ai.sentinel) |s| {718 if (ai.sentinel) |s| {
711 if (index != 0) try writer.writeAll(",");719 if (index != 0) try writer.writeByte(',');
712 try dg.renderValue(writer, ai.elem_type, s, .Other);720 try dg.renderValue(writer, ai.elem_type, s, .Other);
713 }721 }
714 try writer.writeByte('}');722 try writer.writeByte('}');
...@@ -751,7 +759,7 @@ pub const DeclGen = struct {...@@ -751,7 +759,7 @@ pub const DeclGen = struct {
751 else => {759 else => {
752 // In this case we are rendering an error union which has a760 // In this case we are rendering an error union which has a
753 // 0 bits payload.761 // 0 bits payload.
754 return writer.writeAll("0");762 return writer.writeByte('0');
755 },763 },
756 }764 }
757 },765 },
...@@ -827,27 +835,29 @@ pub const DeclGen = struct {...@@ -827,27 +835,29 @@ pub const DeclGen = struct {
827 .Struct => {835 .Struct => {
828 const field_vals = val.castTag(.aggregate).?.data;836 const field_vals = val.castTag(.aggregate).?.data;
829837
830 try writer.writeAll("(");838 try writer.writeByte('(');
831 try dg.renderTypecast(writer, ty);839 try dg.renderTypecast(writer, ty);
832 try writer.writeAll("){");840 try writer.writeAll("){");
833841
834 var i: usize = 0;842 var empty = true;
835 for (field_vals) |field_val, field_index| {843 for (field_vals) |field_val, field_index| {
836 const field_ty = ty.structFieldType(field_index);844 const field_ty = ty.structFieldType(field_index);
837 if (!field_ty.hasRuntimeBits()) continue;845 if (!field_ty.hasRuntimeBits()) continue;
838846
839 if (i != 0) try writer.writeAll(",");847 if (!empty) try writer.writeByte(',');
840 try dg.renderValue(writer, field_ty, field_val, location);848 try dg.renderValue(writer, field_ty, field_val, location);
841 i += 1;849
850 empty = false;
842 }851 }
852 if (empty) try writer.writeByte('0');
843853
844 try writer.writeAll("}");854 try writer.writeByte('}');
845 },855 },
846 .Union => {856 .Union => {
847 const union_obj = val.castTag(.@"union").?.data;857 const union_obj = val.castTag(.@"union").?.data;
848 const layout = ty.unionGetLayout(target);858 const layout = ty.unionGetLayout(target);
849859
850 try writer.writeAll("(");860 try writer.writeByte('(');
851 try dg.renderTypecast(writer, ty);861 try dg.renderTypecast(writer, ty);
852 try writer.writeAll("){");862 try writer.writeAll("){");
853863
...@@ -866,11 +876,11 @@ pub const DeclGen = struct {...@@ -866,11 +876,11 @@ pub const DeclGen = struct {
866 if (field_ty.hasRuntimeBits()) {876 if (field_ty.hasRuntimeBits()) {
867 try writer.print(".{ } = ", .{fmtIdent(field_name)});877 try writer.print(".{ } = ", .{fmtIdent(field_name)});
868 try dg.renderValue(writer, field_ty, union_obj.val, location);878 try dg.renderValue(writer, field_ty, union_obj.val, location);
869 }879 } else try writer.writeByte('0');
870 if (ty.unionTagTypeSafety()) |_| {880 if (ty.unionTagTypeSafety()) |_| {
871 try writer.writeAll("}");881 try writer.writeByte('}');
872 }882 }
873 try writer.writeAll("}");883 try writer.writeByte('}');
874 },884 },
875885
876 .ComptimeInt => unreachable,886 .ComptimeInt => unreachable,
...@@ -913,9 +923,9 @@ pub const DeclGen = struct {...@@ -913,9 +923,9 @@ pub const DeclGen = struct {
913 } else {923 } else {
914 try w.writeAll("void");924 try w.writeAll("void");
915 }925 }
916 try w.writeAll(" ");926 try w.writeByte(' ');
917 try dg.renderDeclName(w, dg.decl_index);927 try dg.renderDeclName(w, dg.decl_index);
918 try w.writeAll("(");928 try w.writeByte('(');
919929
920 var params_written: usize = 0;930 var params_written: usize = 0;
921 for (fn_info.param_types) |param_type, index| {931 for (fn_info.param_types) |param_type, index| {
...@@ -1038,6 +1048,7 @@ pub const DeclGen = struct {...@@ -1038,6 +1048,7 @@ pub const DeclGen = struct {
1038 try buffer.appendSlice("typedef struct {\n");1048 try buffer.appendSlice("typedef struct {\n");
1039 {1049 {
1040 var it = struct_obj.fields.iterator();1050 var it = struct_obj.fields.iterator();
1051 var empty = true;
1041 while (it.next()) |entry| {1052 while (it.next()) |entry| {
1042 const field_ty = entry.value_ptr.ty;1053 const field_ty = entry.value_ptr.ty;
1043 if (!field_ty.hasRuntimeBits()) continue;1054 if (!field_ty.hasRuntimeBits()) continue;
...@@ -1047,7 +1058,10 @@ pub const DeclGen = struct {...@@ -1047,7 +1058,10 @@ pub const DeclGen = struct {
1047 try buffer.append(' ');1058 try buffer.append(' ');
1048 try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment);1059 try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment);
1049 try buffer.appendSlice(";\n");1060 try buffer.appendSlice(";\n");
1061
1062 empty = false;
1050 }1063 }
1064 if (empty) try buffer.appendSlice(" char empty_struct;\n");
1051 }1065 }
1052 try buffer.appendSlice("} ");1066 try buffer.appendSlice("} ");
10531067
...@@ -1076,7 +1090,9 @@ pub const DeclGen = struct {...@@ -1076,7 +1090,9 @@ pub const DeclGen = struct {
10761090
1077 try buffer.appendSlice("typedef struct {\n");1091 try buffer.appendSlice("typedef struct {\n");
1078 {1092 {
1093 var empty = true;
1079 for (tuple.types) |field_ty, i| {1094 for (tuple.types) |field_ty, i| {
1095 if (!field_ty.hasRuntimeBits()) continue;
1080 const val = tuple.values[i];1096 const val = tuple.values[i];
1081 if (val.tag() != .unreachable_value) continue;1097 if (val.tag() != .unreachable_value) continue;
10821098
...@@ -1087,7 +1103,10 @@ pub const DeclGen = struct {...@@ -1087,7 +1103,10 @@ pub const DeclGen = struct {
1087 try buffer.append(' ');1103 try buffer.append(' ');
1088 try dg.renderTypeAndName(writer, field_ty, .{ .bytes = name.items }, .Mut, 0);1104 try dg.renderTypeAndName(writer, field_ty, .{ .bytes = name.items }, .Mut, 0);
1089 try buffer.appendSlice(";\n");1105 try buffer.appendSlice(";\n");
1106
1107 empty = false;
1090 }1108 }
1109 if (empty) try buffer.appendSlice(" char empty_tuple;\n");
1091 }1110 }
1092 try buffer.appendSlice("} ");1111 try buffer.appendSlice("} ");
10931112
...@@ -1129,17 +1148,23 @@ pub const DeclGen = struct {...@@ -1129,17 +1148,23 @@ pub const DeclGen = struct {
1129 }1148 }
11301149
1131 try buffer.appendSlice("union {\n");1150 try buffer.appendSlice("union {\n");
1151 const fields = t.unionFields();
1132 {1152 {
1133 var it = t.unionFields().iterator();1153 var it = fields.iterator();
1154 var empty = true;
1134 while (it.next()) |entry| {1155 while (it.next()) |entry| {
1135 const field_ty = entry.value_ptr.ty;1156 const field_ty = entry.value_ptr.ty;
1136 if (!field_ty.hasRuntimeBits()) continue;1157 if (!field_ty.hasRuntimeBits()) continue;
1158
1137 const alignment = entry.value_ptr.abi_align;1159 const alignment = entry.value_ptr.abi_align;
1138 const name: CValue = .{ .identifier = entry.key_ptr.* };1160 const name: CValue = .{ .identifier = entry.key_ptr.* };
1139 try buffer.append(' ');1161 try buffer.append(' ');
1140 try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment);1162 try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment);
1141 try buffer.appendSlice(";\n");1163 try buffer.appendSlice(";\n");
1164
1165 empty = false;
1142 }1166 }
1167 if (empty) try buffer.appendSlice(" char empty_union;\n");
1143 }1168 }
1144 try buffer.appendSlice("} ");1169 try buffer.appendSlice("} ");
11451170
...@@ -1725,7 +1750,7 @@ pub fn genDecl(o: *Object) !void {...@@ -1725,7 +1750,7 @@ pub fn genDecl(o: *Object) !void {
1725 if (variable.init.tag() != .unreachable_value) {1750 if (variable.init.tag() != .unreachable_value) {
1726 try o.dg.renderValue(w, tv.ty, variable.init, .Other);1751 try o.dg.renderValue(w, tv.ty, variable.init, .Other);
1727 }1752 }
1728 try w.writeAll(";");1753 try w.writeByte(';');
1729 try o.indent_writer.insertNewline();1754 try o.indent_writer.insertNewline();
1730 } else {1755 } else {
1731 const writer = o.writer();1756 const writer = o.writer();
...@@ -2035,7 +2060,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -2035,7 +2060,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
2035 }2060 }
20362061
2037 f.object.indent_writer.popIndent();2062 f.object.indent_writer.popIndent();
2038 try writer.writeAll("}");2063 try writer.writeByte('}');
2039}2064}
20402065
2041fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue {2066fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue {
...@@ -2154,7 +2179,7 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2154,7 +2179,7 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2154 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);2179 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2155 try writer.writeAll(" = ");2180 try writer.writeAll(" = ");
2156 try f.writeCValue(writer, array);2181 try f.writeCValue(writer, array);
2157 try writer.writeAll("[");2182 try writer.writeByte('[');
2158 try f.writeCValue(writer, index);2183 try f.writeCValue(writer, index);
2159 try writer.writeAll("];\n");2184 try writer.writeAll("];\n");
2160 return local;2185 return local;
...@@ -2214,7 +2239,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2214,7 +2239,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
2214 if (is_array) {2239 if (is_array) {
2215 // Insert a memcpy to initialize this array. The source operand is always a pointer2240 // Insert a memcpy to initialize this array. The source operand is always a pointer
2216 // and thus we only need to know size/type information from the local type/dest.2241 // and thus we only need to know size/type information from the local type/dest.
2217 try writer.writeAll(";");2242 try writer.writeByte(';');
2218 try f.object.indent_writer.insertNewline();2243 try f.object.indent_writer.insertNewline();
2219 try writer.writeAll("memcpy(");2244 try writer.writeAll("memcpy(");
2220 try f.writeCValue(writer, local);2245 try f.writeCValue(writer, local);
...@@ -2278,7 +2303,7 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2278,7 +2303,7 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
2278 const local = try f.allocLocal(inst_ty, .Const);2303 const local = try f.allocLocal(inst_ty, .Const);
2279 try writer.writeAll(" = (");2304 try writer.writeAll(" = (");
2280 try f.renderTypecast(writer, inst_ty);2305 try f.renderTypecast(writer, inst_ty);
2281 try writer.writeAll(")");2306 try writer.writeByte(')');
2282 try f.writeCValue(writer, operand);2307 try f.writeCValue(writer, operand);
2283 try writer.writeAll(";\n");2308 try writer.writeAll(";\n");
2284 return local;2309 return local;
...@@ -2381,7 +2406,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2381,7 +2406,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
2381 const new_local = try f.allocLocal(rhs_type, .Const);2406 const new_local = try f.allocLocal(rhs_type, .Const);
2382 try writer.writeAll(" = ");2407 try writer.writeAll(" = ");
2383 try f.writeCValue(writer, src_val);2408 try f.writeCValue(writer, src_val);
2384 try writer.writeAll(";");2409 try writer.writeByte(';');
2385 try f.object.indent_writer.insertNewline();2410 try f.object.indent_writer.insertNewline();
23862411
2387 break :blk new_local;2412 break :blk new_local;
...@@ -2605,7 +2630,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8) !CV...@@ -2605,7 +2630,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8) !CV
2605 const max = intMax(scalar_ty, target, &max_buf);2630 const max = intMax(scalar_ty, target, &max_buf);
26062631
2607 const ret = try f.allocLocal(inst_ty, .Mut);2632 const ret = try f.allocLocal(inst_ty, .Mut);
2608 try w.writeAll(";");2633 try w.writeByte(';');
2609 try f.object.indent_writer.insertNewline();2634 try f.object.indent_writer.insertNewline();
2610 try f.writeCValue(w, ret);2635 try f.writeCValue(w, ret);
26112636
...@@ -2654,10 +2679,7 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2654,10 +2679,7 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
2654 const local = try f.allocLocal(inst_ty, .Const);2679 const local = try f.allocLocal(inst_ty, .Const);
26552680
2656 try writer.writeAll(" = ");2681 try writer.writeAll(" = ");
2657 if (inst_ty.zigTypeTag() == .Bool)2682 try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~');
2658 try writer.writeAll("!")
2659 else
2660 try writer.writeAll("~");
2661 try f.writeCValue(writer, op);2683 try f.writeCValue(writer, op);
2662 try writer.writeAll(";\n");2684 try writer.writeAll(";\n");
26632685
...@@ -2868,7 +2890,7 @@ fn airCall(...@@ -2868,7 +2890,7 @@ fn airCall(
2868 try f.writeCValue(writer, callee);2890 try f.writeCValue(writer, callee);
2869 }2891 }
28702892
2871 try writer.writeAll("(");2893 try writer.writeByte('(');
2872 var args_written: usize = 0;2894 var args_written: usize = 0;
2873 for (args) |arg| {2895 for (args) |arg| {
2874 const ty = f.air.typeOf(arg);2896 const ty = f.air.typeOf(arg);
...@@ -2992,7 +3014,7 @@ fn lowerTry(...@@ -2992,7 +3014,7 @@ fn lowerTry(
2992 try writer.writeAll("if(");3014 try writer.writeAll("if(");
2993 }3015 }
2994 try f.writeCValue(writer, err_union);3016 try f.writeCValue(writer, err_union);
2995 try writer.writeAll(")");3017 try writer.writeByte(')');
2996 break :err;3018 break :err;
2997 }3019 }
2998 if (operand_is_ptr or isByRef(err_union_ty)) {3020 if (operand_is_ptr or isByRef(err_union_ty)) {
...@@ -3066,7 +3088,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3066,7 +3088,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
3066 try writer.writeAll(" = (");3088 try writer.writeAll(" = (");
3067 try f.renderTypecast(writer, inst_ty);3089 try f.renderTypecast(writer, inst_ty);
30683090
3069 try writer.writeAll(")");3091 try writer.writeByte(')');
3070 try f.writeCValue(writer, operand);3092 try f.writeCValue(writer, operand);
3071 try writer.writeAll(";\n");3093 try writer.writeAll(";\n");
3072 return local;3094 return local;
...@@ -3797,7 +3819,7 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3797,7 +3819,7 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue {
37973819
3798 try writer.writeAll(" = (");3820 try writer.writeAll(" = (");
3799 try f.renderTypecast(writer, inst_ty);3821 try f.renderTypecast(writer, inst_ty);
3800 try writer.writeAll(")");3822 try writer.writeByte(')');
3801 try f.writeCValue(writer, operand);3823 try f.writeCValue(writer, operand);
3802 try writer.writeAll(";\n");3824 try writer.writeAll(";\n");
3803 return local;3825 return local;
...@@ -4212,7 +4234,7 @@ fn airNeg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4212,7 +4234,7 @@ fn airNeg(f: *Function, inst: Air.Inst.Index) !CValue {
4212 const inst_ty = f.air.typeOfIndex(inst);4234 const inst_ty = f.air.typeOfIndex(inst);
4213 const operand = try f.resolveInst(un_op);4235 const operand = try f.resolveInst(un_op);
4214 const local = try f.allocLocal(inst_ty, .Const);4236 const local = try f.allocLocal(inst_ty, .Const);
4215 try writer.writeAll("-");4237 try writer.writeByte('-');
4216 try f.writeCValue(writer, operand);4238 try f.writeCValue(writer, operand);
4217 try writer.writeAll(";\n");4239 try writer.writeAll(";\n");
4218 return local;4240 return local;