mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
C backend: avoid memcpy when len=0
As of Clang 18, calling memcpy() with a misaligned pointer trips UBSAN, even if the length is zero. This unfortunately includes any call to `@memcpy` when source or destination are undefined and the length is zero. This patch makes the C backend avoid calling memcpy when the length is zero, thereby avoiding undefined behavior. A zig1.wasm update will be needed in the llvm18 branch to activate this code.
This commit is contained in:
parent
595a7f8b08
commit
fa5011aa31
@ -6799,11 +6799,27 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
const src_ty = f.typeOf(bin_op.rhs);
|
||||
const writer = f.object.writer();
|
||||
|
||||
if (dest_ty.ptrSize(zcu) != .One) {
|
||||
try writer.writeAll("if (");
|
||||
try writeArrayLen(f, writer, dest_ptr, dest_ty);
|
||||
try writer.writeAll(" != 0) ");
|
||||
}
|
||||
try writer.writeAll("memcpy(");
|
||||
try writeSliceOrPtr(f, writer, dest_ptr, dest_ty);
|
||||
try writer.writeAll(", ");
|
||||
try writeSliceOrPtr(f, writer, src_ptr, src_ty);
|
||||
try writer.writeAll(", ");
|
||||
try writeArrayLen(f, writer, dest_ptr, dest_ty);
|
||||
try writer.writeAll(" * sizeof(");
|
||||
try f.renderType(writer, dest_ty.elemType2(zcu));
|
||||
try writer.writeAll("));\n");
|
||||
|
||||
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
|
||||
return .none;
|
||||
}
|
||||
|
||||
fn writeArrayLen(f: *Function, writer: ArrayListWriter, dest_ptr: CValue, dest_ty: Type) !void {
|
||||
const zcu = f.object.dg.zcu;
|
||||
switch (dest_ty.ptrSize(zcu)) {
|
||||
.One => try writer.print("{}", .{
|
||||
try f.fmtIntLiteral(try zcu.intValue(Type.usize, dest_ty.childType(zcu).arrayLen(zcu))),
|
||||
@ -6811,12 +6827,6 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
.Many, .C => unreachable,
|
||||
.Slice => try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" }),
|
||||
}
|
||||
try writer.writeAll(" * sizeof(");
|
||||
try f.renderType(writer, dest_ty.elemType2(zcu));
|
||||
try writer.writeAll("));\n");
|
||||
|
||||
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
|
||||
return .none;
|
||||
}
|
||||
|
||||
fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user