aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-04-24 21:39:03 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-04-25 11:23:41 -0700
commit792bbfa301436fc0ce31bc4072b4765ba1408a55 (patch)
tree4e249d92a5ab600e4ba67893e10ce392b7e506cb /src/codegen
parent5378fdffdcc60a5273021bc9cfc5be917e87c992 (diff)
downloadzig-792bbfa301436fc0ce31bc4072b4765ba1408a55.tar.gz
zig-792bbfa301436fc0ce31bc4072b4765ba1408a55.zip
Sema: fix memcpy alias safety incorrect math
Previously it was not multiplying by the element ABI size. Now, it uses ptr_add instructions which do math based on the element type.
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/llvm.zig54
1 files changed, 34 insertions, 20 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index ac105606e8..94f49e801d 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -7293,39 +7293,53 @@ pub const FuncGen = struct {
fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
- const base_ptr = try self.resolveInst(bin_op.lhs);
+ const ptr = try self.resolveInst(bin_op.lhs);
const offset = try self.resolveInst(bin_op.rhs);
const ptr_ty = self.air.typeOf(bin_op.lhs);
const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());
- if (ptr_ty.ptrSize() == .One) {
- // It's a pointer to an array, so according to LLVM we need an extra GEP index.
- const indices: [2]*llvm.Value = .{
- self.context.intType(32).constNull(), offset,
- };
- return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
- } else {
- const indices: [1]*llvm.Value = .{offset};
- return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
+ switch (ptr_ty.ptrSize()) {
+ .One => {
+ // It's a pointer to an array, so according to LLVM we need an extra GEP index.
+ const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), offset };
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, ptr, &indices, indices.len, "");
+ },
+ .C, .Many => {
+ const indices: [1]*llvm.Value = .{offset};
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, ptr, &indices, indices.len, "");
+ },
+ .Slice => {
+ const base = self.builder.buildExtractValue(ptr, 0, "");
+ const indices: [1]*llvm.Value = .{offset};
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, base, &indices, indices.len, "");
+ },
}
}
fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
- const base_ptr = try self.resolveInst(bin_op.lhs);
+ const ptr = try self.resolveInst(bin_op.lhs);
const offset = try self.resolveInst(bin_op.rhs);
const negative_offset = self.builder.buildNeg(offset, "");
const ptr_ty = self.air.typeOf(bin_op.lhs);
const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());
- if (ptr_ty.ptrSize() == .One) {
- // It's a pointer to an array, so according to LLVM we need an extra GEP index.
- const indices: [2]*llvm.Value = .{
- self.context.intType(32).constNull(), negative_offset,
- };
- return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
- } else {
- const indices: [1]*llvm.Value = .{negative_offset};
- return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
+ switch (ptr_ty.ptrSize()) {
+ .One => {
+ // It's a pointer to an array, so according to LLVM we need an extra GEP index.
+ const indices: [2]*llvm.Value = .{
+ self.context.intType(32).constNull(), negative_offset,
+ };
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, ptr, &indices, indices.len, "");
+ },
+ .C, .Many => {
+ const indices: [1]*llvm.Value = .{negative_offset};
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, ptr, &indices, indices.len, "");
+ },
+ .Slice => {
+ const base = self.builder.buildExtractValue(ptr, 0, "");
+ const indices: [1]*llvm.Value = .{negative_offset};
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, base, &indices, indices.len, "");
+ },
}
}