authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-06 05:17:57-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-25 05:11:28-04:00
loge875530f8f886cbf8272ab18d063252b94a835c9
treecd79c1662d5faf0ee18efc3f14cf009a92618bd3
parent5ae3ac9c431de65c2c075793e98a4a3257ac039e

c: improve lowering of undef values

All remaining behavior test -Wall -Wextra warnings are unused (but set) warnings.

1 files changed, 105 insertions(+), 13 deletions(-)

src/codegen/c.zig+105-13
......@@ -574,7 +574,12 @@ pub const DeclGen = struct {
574574 // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)
575575 // with 'error: expected expression' (including when built with 'zig cc')
576576 .Bool => return writer.writeAll("false"),
577 .Int => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, UndefInt{}, location)}),
577 .Int,
578 .Enum,
579 .ErrorSet,
580 => return writer.print("{x}", .{
581 try dg.fmtIntLiteral(ty, UndefInt{}, location),
582 }),
578583 .Float => switch (ty.tag()) {
579584 .f32 => return writer.print("zig_bitcast_f32_u32({x})", .{
580585 try dg.fmtIntLiteral(Type.u32, UndefInt{}, location),
......@@ -584,25 +589,112 @@ pub const DeclGen = struct {
584589 }),
585590 else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}),
586591 },
587 .Pointer => return writer.print("((void *){x})", .{
588 try dg.fmtIntLiteral(Type.usize, UndefInt{}, location),
589 }),
590 .Struct, .ErrorUnion => {
592 .Pointer => switch (ty.ptrSize()) {
593 .Slice => {
594 try writer.writeByte('(');
595 try dg.renderTypecast(writer, ty);
596 return writer.print("){{(void *){x}, {0x}}}", .{
597 try dg.fmtIntLiteral(Type.usize, UndefInt{}, location),
598 });
599 },
600 .Many, .C, .One => return writer.print("((void *){x})", .{
601 try dg.fmtIntLiteral(Type.usize, UndefInt{}, location),
602 }),
603 },
604 .Optional => {
605 var opt_buf: Type.Payload.ElemType = undefined;
606 const payload_ty = ty.optionalChild(&opt_buf);
607
608 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
609 return dg.renderValue(writer, Type.bool, val, location);
610 }
611
612 if (ty.optionalReprIsPayload()) {
613 return dg.renderValue(writer, payload_ty, val, location);
614 }
615
616 try writer.writeByte('(');
617 try dg.renderTypecast(writer, ty);
618 try writer.writeAll("){ .is_null = ");
619 try dg.renderValue(writer, Type.bool, val, location);
620 try writer.writeAll(", .payload = ");
621 try dg.renderValue(writer, payload_ty, val, location);
622 return writer.writeAll(" }");
623 },
624 .Struct => {
625 try writer.writeByte('(');
626 try dg.renderTypecast(writer, ty);
627 try writer.writeAll("){");
628
629 var empty = true;
630 for (ty.structFields().values()) |field| {
631 if (!field.ty.hasRuntimeBits()) continue;
632
633 if (!empty) try writer.writeByte(',');
634 try dg.renderValue(writer, field.ty, val, location);
635
636 empty = false;
637 }
638 if (empty) try writer.print("{x}", .{
639 try dg.fmtIntLiteral(Type.u8, UndefInt{}, location),
640 });
641
642 return writer.writeByte('}');
643 },
644 .Union => {
591645 try writer.writeByte('(');
592646 try dg.renderTypecast(writer, ty);
593 return writer.writeAll("){0xaau}");
647 try writer.writeAll("){");
648
649 for (ty.unionFields().values()) |field| {
650 if (!field.ty.hasRuntimeBits()) continue;
651 try dg.renderValue(writer, field.ty, val, location);
652 break;
653 } else try writer.print("{x}", .{
654 try dg.fmtIntLiteral(Type.u8, UndefInt{}, location),
655 });
656
657 return writer.writeByte('}');
658 },
659 .ErrorUnion => {
660 try writer.writeByte('(');
661 try dg.renderTypecast(writer, ty);
662 try writer.writeAll("){ .payload = ");
663 try dg.renderValue(writer, ty.errorUnionPayload(), val, location);
664 return writer.print(", .error = {x} }}", .{
665 try dg.fmtIntLiteral(ty.errorUnionSet(), UndefInt{}, location),
666 });
594667 },
595668 .Array => {
596669 try writer.writeByte('{');
597 try dg.renderValue(writer, ty.childType(), val, location);
670
671 const c_len = ty.arrayLenIncludingSentinel();
672 var index: usize = 0;
673 while (index < c_len) : (index += 1) {
674 if (index > 0) try writer.writeAll(", ");
675 try dg.renderValue(writer, ty.childType(), val, location);
676 }
677
598678 return writer.writeByte('}');
599679 },
600 else => {
601 // This should lower to 0xaa bytes in safe modes, and for unsafe modes should
602 // lower to leaving variables uninitialized (that might need to be implemented
603 // outside of this function).
604 return writer.writeAll("{}");
605 },
680 .ComptimeInt,
681 .ComptimeFloat,
682 .Type,
683 .EnumLiteral,
684 .Void,
685 .NoReturn,
686 .Undefined,
687 .Null,
688 .BoundFn,
689 .Opaque,
690 => unreachable,
691 .Fn,
692 .Frame,
693 .AnyFrame,
694 .Vector,
695 => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{
696 @tagName(tag),
697 }),
606698 }
607699 }
608700 switch (ty.zigTypeTag()) {