| ... | ... | @@ -139,6 +139,7 @@ pub const Block = struct { |
| 139 | 139 | |
| 140 | 140 | is_comptime: bool, |
| 141 | 141 | is_typeof: bool = false, |
| 142 | is_coerce_result_ptr: bool = false, |
| 142 | 143 | |
| 143 | 144 | /// when null, it is determined by build mode, changed by @setRuntimeSafety |
| 144 | 145 | want_safety: ?bool = null, |
| ... | ... | @@ -1734,9 +1735,20 @@ fn failWithErrorSetCodeMissing( |
| 1734 | 1735 | }); |
| 1735 | 1736 | } |
| 1736 | 1737 | |
| 1737 | | fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: Type, val: Value) CompileError { |
| 1738 | fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: Type, val: Value, vector_index: usize) CompileError { |
| 1739 | if (int_ty.zigTypeTag() == .Vector) { |
| 1740 | const msg = msg: { |
| 1741 | const msg = try sema.errMsg(block, src, "overflow of vector type '{}' with value '{}'", .{ |
| 1742 | int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod), |
| 1743 | }); |
| 1744 | errdefer msg.destroy(sema.gpa); |
| 1745 | try sema.errNote(block, src, msg, "when computing vector element at index '{d}'", .{vector_index}); |
| 1746 | break :msg msg; |
| 1747 | }; |
| 1748 | return sema.failWithOwnedErrorMsg(block, msg); |
| 1749 | } |
| 1738 | 1750 | return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{ |
| 1739 | | int_ty.fmt(sema.mod), val.fmtValue(Type.@"comptime_int", sema.mod), |
| 1751 | int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod), |
| 1740 | 1752 | }); |
| 1741 | 1753 | } |
| 1742 | 1754 | |
| ... | ... | @@ -1971,6 +1983,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 1971 | 1983 | // kind of transformations to make on the result pointer. |
| 1972 | 1984 | var trash_block = block.makeSubBlock(); |
| 1973 | 1985 | trash_block.is_comptime = false; |
| 1986 | trash_block.is_coerce_result_ptr = true; |
| 1974 | 1987 | defer trash_block.instructions.deinit(sema.gpa); |
| 1975 | 1988 | |
| 1976 | 1989 | const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr)); |
| ... | ... | @@ -10453,8 +10466,9 @@ fn analyzeArithmetic( |
| 10453 | 10466 | if (maybe_rhs_val) |rhs_val| { |
| 10454 | 10467 | if (is_int) { |
| 10455 | 10468 | const sum = try sema.intAdd(block, src, lhs_val, rhs_val, resolved_type); |
| 10456 | | if (!(try sema.intFitsInType(block, src, sum, resolved_type))) { |
| 10457 | | return sema.failWithIntegerOverflow(block, src, resolved_type, sum); |
| 10469 | var vector_index: usize = undefined; |
| 10470 | if (!(try sema.intFitsInType(block, src, sum, resolved_type, &vector_index))) { |
| 10471 | return sema.failWithIntegerOverflow(block, src, resolved_type, sum, vector_index); |
| 10458 | 10472 | } |
| 10459 | 10473 | return sema.addConstant(resolved_type, sum); |
| 10460 | 10474 | } else { |
| ... | ... | @@ -10547,8 +10561,9 @@ fn analyzeArithmetic( |
| 10547 | 10561 | if (maybe_rhs_val) |rhs_val| { |
| 10548 | 10562 | if (is_int) { |
| 10549 | 10563 | const diff = try sema.intSub(block, src, lhs_val, rhs_val, resolved_type); |
| 10550 | | if (!(try sema.intFitsInType(block, src, diff, resolved_type))) { |
| 10551 | | return sema.failWithIntegerOverflow(block, src, resolved_type, diff); |
| 10564 | var vector_index: usize = undefined; |
| 10565 | if (!(try sema.intFitsInType(block, src, diff, resolved_type, &vector_index))) { |
| 10566 | return sema.failWithIntegerOverflow(block, src, resolved_type, diff, vector_index); |
| 10552 | 10567 | } |
| 10553 | 10568 | return sema.addConstant(resolved_type, diff); |
| 10554 | 10569 | } else { |
| ... | ... | @@ -10921,8 +10936,9 @@ fn analyzeArithmetic( |
| 10921 | 10936 | } |
| 10922 | 10937 | if (is_int) { |
| 10923 | 10938 | const product = try lhs_val.intMul(rhs_val, resolved_type, sema.arena, target); |
| 10924 | | if (!(try sema.intFitsInType(block, src, product, resolved_type))) { |
| 10925 | | return sema.failWithIntegerOverflow(block, src, resolved_type, product); |
| 10939 | var vector_index: usize = undefined; |
| 10940 | if (!(try sema.intFitsInType(block, src, product, resolved_type, &vector_index))) { |
| 10941 | return sema.failWithIntegerOverflow(block, src, resolved_type, product, vector_index); |
| 10926 | 10942 | } |
| 10927 | 10943 | return sema.addConstant(resolved_type, product); |
| 10928 | 10944 | } else { |
| ... | ... | @@ -16456,15 +16472,15 @@ fn analyzeShuffle( |
| 16456 | 16472 | } |
| 16457 | 16473 | if (unsigned >= operand_info[chosen][0]) { |
| 16458 | 16474 | const msg = msg: { |
| 16459 | | const msg = try sema.errMsg(block, mask_src, "mask index {d} has out-of-bounds selection", .{i}); |
| 16475 | const msg = try sema.errMsg(block, mask_src, "mask index '{d}' has out-of-bounds selection", .{i}); |
| 16460 | 16476 | errdefer msg.destroy(sema.gpa); |
| 16461 | 16477 | |
| 16462 | | try sema.errNote(block, operand_info[chosen][1], msg, "selected index {d} out of bounds of '{}'", .{ |
| 16478 | try sema.errNote(block, operand_info[chosen][1], msg, "selected index '{d}' out of bounds of '{}'", .{ |
| 16463 | 16479 | unsigned, |
| 16464 | 16480 | operand_info[chosen][2].fmt(sema.mod), |
| 16465 | 16481 | }); |
| 16466 | 16482 | |
| 16467 | | if (chosen == 1) { |
| 16483 | if (chosen == 0) { |
| 16468 | 16484 | try sema.errNote(block, b_src, msg, "selections from the second vector are specified with negative numbers", .{}); |
| 16469 | 16485 | } |
| 16470 | 16486 | |
| ... | ... | @@ -17750,7 +17766,7 @@ fn zirBuiltinExtern( |
| 17750 | 17766 | } |
| 17751 | 17767 | |
| 17752 | 17768 | fn requireFunctionBlock(sema: *Sema, block: *Block, src: LazySrcLoc) !void { |
| 17753 | | if (sema.func == null and !block.is_typeof) { |
| 17769 | if (sema.func == null and !block.is_typeof and !block.is_coerce_result_ptr) { |
| 17754 | 17770 | return sema.fail(block, src, "instruction illegal outside function body", .{}); |
| 17755 | 17771 | } |
| 17756 | 17772 | } |
| ... | ... | @@ -19881,7 +19897,7 @@ fn coerce( |
| 19881 | 19897 | .Int, .ComptimeInt => { |
| 19882 | 19898 | if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| { |
| 19883 | 19899 | // comptime known integer to other number |
| 19884 | | if (!(try sema.intFitsInType(block, inst_src, val, dest_ty))) { |
| 19900 | if (!(try sema.intFitsInType(block, inst_src, val, dest_ty, null))) { |
| 19885 | 19901 | return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) }); |
| 19886 | 19902 | } |
| 19887 | 19903 | return try sema.addConstant(dest_ty, val); |
| ... | ... | @@ -25829,7 +25845,7 @@ fn floatToIntScalar( |
| 25829 | 25845 | else |
| 25830 | 25846 | try Value.Tag.int_big_positive.create(sema.arena, result_limbs); |
| 25831 | 25847 | |
| 25832 | | if (!(try sema.intFitsInType(block, src, result, int_ty))) { |
| 25848 | if (!(try sema.intFitsInType(block, src, result, int_ty, null))) { |
| 25833 | 25849 | return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{ |
| 25834 | 25850 | val.fmtValue(float_ty, sema.mod), int_ty.fmt(sema.mod), |
| 25835 | 25851 | }); |
| ... | ... | @@ -25845,6 +25861,7 @@ fn intFitsInType( |
| 25845 | 25861 | src: LazySrcLoc, |
| 25846 | 25862 | self: Value, |
| 25847 | 25863 | ty: Type, |
| 25864 | vector_index: ?*usize, |
| 25848 | 25865 | ) CompileError!bool { |
| 25849 | 25866 | const target = sema.mod.getTarget(); |
| 25850 | 25867 | switch (self.tag()) { |
| ... | ... | @@ -25954,8 +25971,9 @@ fn intFitsInType( |
| 25954 | 25971 | |
| 25955 | 25972 | .aggregate => { |
| 25956 | 25973 | assert(ty.zigTypeTag() == .Vector); |
| 25957 | | for (self.castTag(.aggregate).?.data) |elem| { |
| 25958 | | if (!(try sema.intFitsInType(block, src, elem, ty.scalarType()))) { |
| 25974 | for (self.castTag(.aggregate).?.data) |elem, i| { |
| 25975 | if (!(try sema.intFitsInType(block, src, elem, ty.scalarType(), null))) { |
| 25976 | if (vector_index) |some| some.* = i; |
| 25959 | 25977 | return false; |
| 25960 | 25978 | } |
| 25961 | 25979 | } |
| ... | ... | @@ -25993,7 +26011,7 @@ fn enumHasInt( |
| 25993 | 26011 | int: Value, |
| 25994 | 26012 | ) CompileError!bool { |
| 25995 | 26013 | switch (ty.tag()) { |
| 25996 | | .enum_nonexhaustive => return sema.intFitsInType(block, src, int, ty), |
| 26014 | .enum_nonexhaustive => return sema.intFitsInType(block, src, int, ty, null), |
| 25997 | 26015 | .enum_full => { |
| 25998 | 26016 | const enum_full = ty.castTag(.enum_full).?.data; |
| 25999 | 26017 | const tag_ty = enum_full.tag_ty; |