C backend: fix ptr comparison of array ptrs when one is null-terminated

This commit is contained in:
Andrew Kelley 2023-04-27 14:01:16 -07:00
parent 6261c13731
commit 73d3fb9883
4 changed files with 46 additions and 22 deletions

View File

@ -3858,7 +3858,7 @@ fn airCmpOp(
try reap(f, inst, &.{ data.lhs, data.rhs });
const rhs_ty = f.air.typeOf(data.rhs);
const need_cast = lhs_ty.isSinglePointer() != rhs_ty.isSinglePointer();
const need_cast = lhs_ty.isSinglePointer() or rhs_ty.isSinglePointer();
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
const v = try Vectorize.start(f, inst, writer, lhs_ty);

View File

@ -177,6 +177,7 @@ test {
_ = @import("behavior/math.zig");
_ = @import("behavior/maximum_minimum.zig");
_ = @import("behavior/member_func.zig");
_ = @import("behavior/memcpy.zig");
_ = @import("behavior/memset.zig");
_ = @import("behavior/merge_error_sets.zig");
_ = @import("behavior/muladd.zig");

44
test/behavior/memcpy.zig Normal file
View File

@ -0,0 +1,44 @@
const std = @import("std");
const builtin = @import("builtin");
const expect = std.testing.expect;
test "memcpy and memset intrinsics" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
try testMemcpyMemset();
try comptime testMemcpyMemset();
}
fn testMemcpyMemset() !void {
var foo: [20]u8 = undefined;
var bar: [20]u8 = undefined;
@memset(&foo, 'A');
@memcpy(&bar, &foo);
try expect(bar[0] == 'A');
try expect(bar[11] == 'A');
try expect(bar[19] == 'A');
}
test "@memcpy with both operands single-ptr-to-array, one is null-terminated" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
try testMemcpyBothSinglePtrArrayOneIsNullTerminated();
try comptime testMemcpyBothSinglePtrArrayOneIsNullTerminated();
}
fn testMemcpyBothSinglePtrArrayOneIsNullTerminated() !void {
var buf: [100]u8 = undefined;
const suffix = "hello";
@memcpy(buf[buf.len - suffix.len ..], suffix);
try expect(buf[95] == 'h');
try expect(buf[96] == 'e');
try expect(buf[97] == 'l');
try expect(buf[98] == 'l');
try expect(buf[99] == 'o');
}

View File

@ -142,24 +142,3 @@ test "memset with large array element, comptime known" {
for (buf[3]) |elem| try expect(elem == 0);
for (buf[4]) |elem| try expect(elem == 0);
}
test "memcpy and memset intrinsics" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
try testMemcpyMemset();
try comptime testMemcpyMemset();
}
fn testMemcpyMemset() !void {
var foo: [20]u8 = undefined;
var bar: [20]u8 = undefined;
@memset(&foo, 'A');
@memcpy(&bar, &foo);
try expect(bar[0] == 'A');
try expect(bar[11] == 'A');
try expect(bar[19] == 'A');
}