@@ -3648,7 +3648,7 @@ fn indexablePtrLen(
3648
3648
const object_ty = sema.typeOf(object);
3649
3649
const is_pointer_to = object_ty.isSinglePointer(zcu);
3650
3650
const indexable_ty = if (is_pointer_to) object_ty.childType(zcu) else object_ty;
3651
- try checkIndexable(sema, block, src, indexable_ty);
3651
+ try sema. checkIndexable(block, src, indexable_ty);
3652
3652
const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls);
3653
3653
return sema.fieldVal(block, src, object, field_name, src);
3654
3654
}
@@ -10103,6 +10103,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10103
10103
}
10104
10104
try sema.requireRuntimeBlock(block, block.nodeOffset(inst_data.src_node), ptr_src);
10105
10105
try sema.validateRuntimeValue(block, ptr_src, operand);
10106
+ try sema.checkLogicalPtrOperation(block, ptr_src, ptr_ty);
10106
10107
if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) {
10107
10108
return block.addBitCast(dest_ty, operand);
10108
10109
}
@@ -16389,6 +16390,8 @@ fn analyzeArithmetic(
16389
16390
};
16390
16391
16391
16392
try sema.requireRuntimeBlock(block, src, runtime_src);
16393
+ try sema.checkLogicalPtrOperation(block, src, lhs_ty);
16394
+ try sema.checkLogicalPtrOperation(block, src, rhs_ty);
16392
16395
const lhs_int = try block.addBitCast(.usize, lhs);
16393
16396
const rhs_int = try block.addBitCast(.usize, rhs);
16394
16397
const address = try block.addBinOp(.sub_wrap, lhs_int, rhs_int);
@@ -16620,24 +16623,7 @@ fn analyzePtrArithmetic(
16620
16623
};
16621
16624
16622
16625
try sema.requireRuntimeBlock(block, op_src, runtime_src);
16623
-
16624
- const target = zcu.getTarget();
16625
- if (target_util.arePointersLogical(target, ptr_info.flags.address_space)) {
16626
- return sema.failWithOwnedErrorMsg(block, msg: {
16627
- const msg = try sema.errMsg(op_src, "illegal pointer arithmetic on pointer of type '{}'", .{ptr_ty.fmt(pt)});
16628
- errdefer msg.destroy(sema.gpa);
16629
-
16630
- const backend = target_util.zigBackend(target, zcu.comp.config.use_llvm);
16631
- try sema.errNote(op_src, msg, "arithmetic cannot be performed on pointers with address space '{s}' on target {s}-{s} by compiler backend {s}", .{
16632
- @tagName(ptr_info.flags.address_space),
16633
- target.cpu.arch.genericName(),
16634
- @tagName(target.os.tag),
16635
- @tagName(backend),
16636
- });
16637
-
16638
- break :msg msg;
16639
- });
16640
- }
16626
+ try sema.checkLogicalPtrOperation(block, op_src, ptr_ty);
16641
16627
16642
16628
return block.addInst(.{
16643
16629
.tag = air_tag,
@@ -22501,6 +22487,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22501
22487
});
22502
22488
}
22503
22489
try sema.requireRuntimeBlock(block, src, operand_src);
22490
+ try sema.checkLogicalPtrOperation(block, src, ptr_ty);
22504
22491
if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) {
22505
22492
if (block.wantSafety() and (try elem_ty.hasRuntimeBitsSema(pt) or elem_ty.zigTypeTag(zcu) == .@"fn")) {
22506
22493
if (!ptr_ty.isAllowzeroPtr(zcu)) {
@@ -23165,8 +23152,9 @@ fn ptrCastFull(
23165
23152
23166
23153
try sema.validateRuntimeValue(block, operand_src, operand);
23167
23154
23168
- const need_null_check = block.wantSafety() and operand_ty.ptrAllowsZero(zcu) and !dest_ty.ptrAllowsZero(zcu);
23169
- const need_align_check = block.wantSafety() and dest_align.compare(.gt, src_align);
23155
+ const can_cast_to_int = !target_util.arePointersLogical(zcu.getTarget(), operand_ty.ptrAddressSpace(zcu));
23156
+ const need_null_check = can_cast_to_int and block.wantSafety() and operand_ty.ptrAllowsZero(zcu) and !dest_ty.ptrAllowsZero(zcu);
23157
+ const need_align_check = can_cast_to_int and block.wantSafety() and dest_align.compare(.gt, src_align);
23170
23158
23171
23159
// `operand` might be a slice. If `need_operand_ptr`, we'll populate `operand_ptr` with the raw pointer.
23172
23160
const need_operand_ptr = src_info.flags.size != .slice or // we already have it
@@ -23832,6 +23820,32 @@ fn checkPtrType(
23832
23820
return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(pt)});
23833
23821
}
23834
23822
23823
+ fn checkLogicalPtrOperation(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
23824
+ const pt = sema.pt;
23825
+ const zcu = pt.zcu;
23826
+ if (zcu.intern_pool.indexToKey(ty.toIntern()) == .ptr_type) {
23827
+ const target = zcu.getTarget();
23828
+ const as = ty.ptrAddressSpace(zcu);
23829
+ if (target_util.arePointersLogical(target, as)) {
23830
+ return sema.failWithOwnedErrorMsg(block, msg: {
23831
+ const msg = try sema.errMsg(src, "illegal operation on logical pointer of type '{}'", .{ty.fmt(pt)});
23832
+ errdefer msg.destroy(sema.gpa);
23833
+ try sema.errNote(
23834
+ src,
23835
+ msg,
23836
+ "cannot perform arithmetic on pointers with address space '{s}' on target {s}-{s}",
23837
+ .{
23838
+ @tagName(as),
23839
+ target.cpu.arch.genericName(),
23840
+ @tagName(target.os.tag),
23841
+ },
23842
+ );
23843
+ break :msg msg;
23844
+ });
23845
+ }
23846
+ }
23847
+ }
23848
+
23835
23849
fn checkVectorElemType(
23836
23850
sema: *Sema,
23837
23851
block: *Block,
@@ -28326,7 +28340,7 @@ fn elemPtr(
28326
28340
.pointer => indexable_ptr_ty.childType(zcu),
28327
28341
else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(pt)}),
28328
28342
};
28329
- try checkIndexable(sema, block, src, indexable_ty);
28343
+ try sema. checkIndexable(block, src, indexable_ty);
28330
28344
28331
28345
const elem_ptr = switch (indexable_ty.zigTypeTag(zcu)) {
28332
28346
.array, .vector => try sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init, oob_safety),
@@ -28362,7 +28376,7 @@ fn elemPtrOneLayerOnly(
28362
28376
const pt = sema.pt;
28363
28377
const zcu = pt.zcu;
28364
28378
28365
- try checkIndexable(sema, block, src, indexable_ty);
28379
+ try sema. checkIndexable(block, src, indexable_ty);
28366
28380
28367
28381
switch (indexable_ty.ptrSize(zcu)) {
28368
28382
.slice => return sema.elemPtrSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
@@ -28376,6 +28390,8 @@ fn elemPtrOneLayerOnly(
28376
28390
const elem_ptr = try ptr_val.ptrElem(index, pt);
28377
28391
return Air.internedToRef(elem_ptr.toIntern());
28378
28392
}
28393
+
28394
+ try sema.checkLogicalPtrOperation(block, src, indexable_ty);
28379
28395
const result_ty = try indexable_ty.elemPtrType(null, pt);
28380
28396
28381
28397
return block.addPtrElemPtr(indexable, elem_index, result_ty);
@@ -28412,7 +28428,7 @@ fn elemVal(
28412
28428
const pt = sema.pt;
28413
28429
const zcu = pt.zcu;
28414
28430
28415
- try checkIndexable(sema, block, src, indexable_ty);
28431
+ try sema. checkIndexable(block, src, indexable_ty);
28416
28432
28417
28433
// TODO in case of a vector of pointers, we need to detect whether the element
28418
28434
// index is a scalar or vector instead of unconditionally casting to usize.
@@ -28438,6 +28454,7 @@ fn elemVal(
28438
28454
return Air.internedToRef((try pt.getCoerced(elem_val, elem_ty)).toIntern());
28439
28455
}
28440
28456
28457
+ try sema.checkLogicalPtrOperation(block, src, indexable_ty);
28441
28458
return block.addBinOp(.ptr_elem_val, indexable, elem_index);
28442
28459
},
28443
28460
.one => {
@@ -28477,6 +28494,9 @@ fn validateRuntimeElemAccess(
28477
28494
parent_ty: Type,
28478
28495
parent_src: LazySrcLoc,
28479
28496
) CompileError!void {
28497
+ const pt = sema.pt;
28498
+ const zcu = pt.zcu;
28499
+
28480
28500
if (try elem_ty.comptimeOnlySema(sema.pt)) {
28481
28501
const msg = msg: {
28482
28502
const msg = try sema.errMsg(
@@ -28492,6 +28512,14 @@ fn validateRuntimeElemAccess(
28492
28512
};
28493
28513
return sema.failWithOwnedErrorMsg(block, msg);
28494
28514
}
28515
+
28516
+ if (zcu.intern_pool.indexToKey(parent_ty.toIntern()) == .ptr_type) {
28517
+ const target = zcu.getTarget();
28518
+ const as = parent_ty.ptrAddressSpace(zcu);
28519
+ if (target_util.arePointersLogical(target, as)) {
28520
+ return sema.fail(block, elem_index_src, "cannot access element of logical pointer '{}'", .{parent_ty.fmt(pt)});
28521
+ }
28522
+ }
28495
28523
}
28496
28524
28497
28525
fn tupleFieldPtr(
@@ -31158,6 +31186,7 @@ fn coerceCompatiblePtrs(
31158
31186
if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero(zcu) and
31159
31187
(try dest_ty.elemType2(zcu).hasRuntimeBitsSema(pt) or dest_ty.elemType2(zcu).zigTypeTag(zcu) == .@"fn"))
31160
31188
{
31189
+ try sema.checkLogicalPtrOperation(block, inst_src, inst_ty);
31161
31190
const actual_ptr = if (inst_ty.isSlice(zcu))
31162
31191
try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty)
31163
31192
else
0 commit comments