| ... | @@ -3648,7 +3648,7 @@ fn indexablePtrLen( | ... | @@ -3648,7 +3648,7 @@ fn indexablePtrLen( |
| 3648 | const object_ty = sema.typeOf(object); | 3648 | const object_ty = sema.typeOf(object); |
| 3649 | const is_pointer_to = object_ty.isSinglePointer(zcu); | 3649 | const is_pointer_to = object_ty.isSinglePointer(zcu); |
| 3650 | const indexable_ty = if (is_pointer_to) object_ty.childType(zcu) else object_ty; | 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 | const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls); | 3652 | const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls); |
| 3653 | return sema.fieldVal(block, src, object, field_name, src); | 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,6 +10103,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10103 | } | 10103 | } |
| 10104 | try sema.requireRuntimeBlock(block, block.nodeOffset(inst_data.src_node), ptr_src); | 10104 | try sema.requireRuntimeBlock(block, block.nodeOffset(inst_data.src_node), ptr_src); |
| 10105 | try sema.validateRuntimeValue(block, ptr_src, operand); | 10105 | try sema.validateRuntimeValue(block, ptr_src, operand); |
| | 10106 | try sema.checkLogicalPtrOperation(block, ptr_src, ptr_ty); |
| 10106 | if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) { | 10107 | if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) { |
| 10107 | return block.addBitCast(dest_ty, operand); | 10108 | return block.addBitCast(dest_ty, operand); |
| 10108 | } | 10109 | } |
| ... | @@ -16389,6 +16390,8 @@ fn analyzeArithmetic( | ... | @@ -16389,6 +16390,8 @@ fn analyzeArithmetic( |
| 16389 | }; | 16390 | }; |
| 16390 | | 16391 | |
| 16391 | try sema.requireRuntimeBlock(block, src, runtime_src); | 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 | const lhs_int = try block.addBitCast(.usize, lhs); | 16395 | const lhs_int = try block.addBitCast(.usize, lhs); |
| 16393 | const rhs_int = try block.addBitCast(.usize, rhs); | 16396 | const rhs_int = try block.addBitCast(.usize, rhs); |
| 16394 | const address = try block.addBinOp(.sub_wrap, lhs_int, rhs_int); | 16397 | const address = try block.addBinOp(.sub_wrap, lhs_int, rhs_int); |
| ... | @@ -16620,24 +16623,7 @@ fn analyzePtrArithmetic( | ... | @@ -16620,24 +16623,7 @@ fn analyzePtrArithmetic( |
| 16620 | }; | 16623 | }; |
| 16621 | | 16624 | |
| 16622 | try sema.requireRuntimeBlock(block, op_src, runtime_src); | 16625 | try sema.requireRuntimeBlock(block, op_src, runtime_src); |
| 16623 | | 16626 | try sema.checkLogicalPtrOperation(block, op_src, ptr_ty); |
| 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 | } | | |
| 16641 | | 16627 | |
| 16642 | return block.addInst(.{ | 16628 | return block.addInst(.{ |
| 16643 | .tag = air_tag, | 16629 | .tag = air_tag, |
| ... | @@ -22501,6 +22487,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -22501,6 +22487,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22501 | }); | 22487 | }); |
| 22502 | } | 22488 | } |
| 22503 | try sema.requireRuntimeBlock(block, src, operand_src); | 22489 | try sema.requireRuntimeBlock(block, src, operand_src); |
| | 22490 | try sema.checkLogicalPtrOperation(block, src, ptr_ty); |
| 22504 | if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) { | 22491 | if (!is_vector or zcu.backendSupportsFeature(.all_vector_instructions)) { |
| 22505 | if (block.wantSafety() and (try elem_ty.hasRuntimeBitsSema(pt) or elem_ty.zigTypeTag(zcu) == .@"fn")) { | 22492 | if (block.wantSafety() and (try elem_ty.hasRuntimeBitsSema(pt) or elem_ty.zigTypeTag(zcu) == .@"fn")) { |
| 22506 | if (!ptr_ty.isAllowzeroPtr(zcu)) { | 22493 | if (!ptr_ty.isAllowzeroPtr(zcu)) { |
| ... | @@ -23165,8 +23152,9 @@ fn ptrCastFull( | ... | @@ -23165,8 +23152,9 @@ fn ptrCastFull( |
| 23165 | | 23152 | |
| 23166 | try sema.validateRuntimeValue(block, operand_src, operand); | 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); | 23155 | const can_cast_to_int = !target_util.arePointersLogical(zcu.getTarget(), operand_ty.ptrAddressSpace(zcu)); |
| 23169 | const need_align_check = block.wantSafety() and dest_align.compare(.gt, src_align); | 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 | // `operand` might be a slice. If `need_operand_ptr`, we'll populate `operand_ptr` with the raw pointer. | 23159 | // `operand` might be a slice. If `need_operand_ptr`, we'll populate `operand_ptr` with the raw pointer. |
| 23172 | const need_operand_ptr = src_info.flags.size != .slice or // we already have it | 23160 | const need_operand_ptr = src_info.flags.size != .slice or // we already have it |
| ... | @@ -23832,6 +23820,32 @@ fn checkPtrType( | ... | @@ -23832,6 +23820,32 @@ fn checkPtrType( |
| 23832 | return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(pt)}); | 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 | fn checkVectorElemType( | 23849 | fn checkVectorElemType( |
| 23836 | sema: *Sema, | 23850 | sema: *Sema, |
| 23837 | block: *Block, | 23851 | block: *Block, |
| ... | @@ -28326,7 +28340,7 @@ fn elemPtr( | ... | @@ -28326,7 +28340,7 @@ fn elemPtr( |
| 28326 | .pointer => indexable_ptr_ty.childType(zcu), | 28340 | .pointer => indexable_ptr_ty.childType(zcu), |
| 28327 | else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(pt)}), | 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 | const elem_ptr = switch (indexable_ty.zigTypeTag(zcu)) { | 28345 | const elem_ptr = switch (indexable_ty.zigTypeTag(zcu)) { |
| 28332 | .array, .vector => try sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init, oob_safety), | 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,7 +28376,7 @@ fn elemPtrOneLayerOnly( |
| 28362 | const pt = sema.pt; | 28376 | const pt = sema.pt; |
| 28363 | const zcu = pt.zcu; | 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 | switch (indexable_ty.ptrSize(zcu)) { | 28381 | switch (indexable_ty.ptrSize(zcu)) { |
| 28368 | .slice => return sema.elemPtrSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety), | 28382 | .slice => return sema.elemPtrSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety), |
| ... | @@ -28376,6 +28390,8 @@ fn elemPtrOneLayerOnly( | ... | @@ -28376,6 +28390,8 @@ fn elemPtrOneLayerOnly( |
| 28376 | const elem_ptr = try ptr_val.ptrElem(index, pt); | 28390 | const elem_ptr = try ptr_val.ptrElem(index, pt); |
| 28377 | return Air.internedToRef(elem_ptr.toIntern()); | 28391 | return Air.internedToRef(elem_ptr.toIntern()); |
| 28378 | } | 28392 | } |
| | 28393 | |
| | 28394 | try sema.checkLogicalPtrOperation(block, src, indexable_ty); |
| 28379 | const result_ty = try indexable_ty.elemPtrType(null, pt); | 28395 | const result_ty = try indexable_ty.elemPtrType(null, pt); |
| 28380 | | 28396 | |
| 28381 | return block.addPtrElemPtr(indexable, elem_index, result_ty); | 28397 | return block.addPtrElemPtr(indexable, elem_index, result_ty); |
| ... | @@ -28412,7 +28428,7 @@ fn elemVal( | ... | @@ -28412,7 +28428,7 @@ fn elemVal( |
| 28412 | const pt = sema.pt; | 28428 | const pt = sema.pt; |
| 28413 | const zcu = pt.zcu; | 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 | // TODO in case of a vector of pointers, we need to detect whether the element | 28433 | // TODO in case of a vector of pointers, we need to detect whether the element |
| 28418 | // index is a scalar or vector instead of unconditionally casting to usize. | 28434 | // index is a scalar or vector instead of unconditionally casting to usize. |
| ... | @@ -28438,6 +28454,7 @@ fn elemVal( | ... | @@ -28438,6 +28454,7 @@ fn elemVal( |
| 28438 | return Air.internedToRef((try pt.getCoerced(elem_val, elem_ty)).toIntern()); | 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 | return block.addBinOp(.ptr_elem_val, indexable, elem_index); | 28458 | return block.addBinOp(.ptr_elem_val, indexable, elem_index); |
| 28442 | }, | 28459 | }, |
| 28443 | .one => { | 28460 | .one => { |
| ... | @@ -28477,6 +28494,9 @@ fn validateRuntimeElemAccess( | ... | @@ -28477,6 +28494,9 @@ fn validateRuntimeElemAccess( |
| 28477 | parent_ty: Type, | 28494 | parent_ty: Type, |
| 28478 | parent_src: LazySrcLoc, | 28495 | parent_src: LazySrcLoc, |
| 28479 | ) CompileError!void { | 28496 | ) CompileError!void { |
| | 28497 | const pt = sema.pt; |
| | 28498 | const zcu = pt.zcu; |
| | 28499 | |
| 28480 | if (try elem_ty.comptimeOnlySema(sema.pt)) { | 28500 | if (try elem_ty.comptimeOnlySema(sema.pt)) { |
| 28481 | const msg = msg: { | 28501 | const msg = msg: { |
| 28482 | const msg = try sema.errMsg( | 28502 | const msg = try sema.errMsg( |
| ... | @@ -28492,6 +28512,14 @@ fn validateRuntimeElemAccess( | ... | @@ -28492,6 +28512,14 @@ fn validateRuntimeElemAccess( |
| 28492 | }; | 28512 | }; |
| 28493 | return sema.failWithOwnedErrorMsg(block, msg); | 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 | fn tupleFieldPtr( | 28525 | fn tupleFieldPtr( |
| ... | @@ -31158,6 +31186,7 @@ fn coerceCompatiblePtrs( | ... | @@ -31158,6 +31186,7 @@ fn coerceCompatiblePtrs( |
| 31158 | if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero(zcu) and | 31186 | if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero(zcu) and |
| 31159 | (try dest_ty.elemType2(zcu).hasRuntimeBitsSema(pt) or dest_ty.elemType2(zcu).zigTypeTag(zcu) == .@"fn")) | 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 | const actual_ptr = if (inst_ty.isSlice(zcu)) | 31190 | const actual_ptr = if (inst_ty.isSlice(zcu)) |
| 31162 | try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty) | 31191 | try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty) |
| 31163 | else | 31192 | else |