| ... | @@ -139,6 +139,7 @@ pub const Block = struct { | ... | @@ -139,6 +139,7 @@ pub const Block = struct { |
| 139 | | 139 | |
| 140 | is_comptime: bool, | 140 | is_comptime: bool, |
| 141 | is_typeof: bool = false, | 141 | is_typeof: bool = false, |
| | 142 | is_coerce_result_ptr: bool = false, |
| 142 | | 143 | |
| 143 | /// when null, it is determined by build mode, changed by @setRuntimeSafety | 144 | /// when null, it is determined by build mode, changed by @setRuntimeSafety |
| 144 | want_safety: ?bool = null, | 145 | want_safety: ?bool = null, |
| ... | @@ -1734,9 +1735,20 @@ fn failWithErrorSetCodeMissing( | ... | @@ -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 | return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{ | 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,6 +1983,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 1971 | // kind of transformations to make on the result pointer. | 1983 | // kind of transformations to make on the result pointer. |
| 1972 | var trash_block = block.makeSubBlock(); | 1984 | var trash_block = block.makeSubBlock(); |
| 1973 | trash_block.is_comptime = false; | 1985 | trash_block.is_comptime = false; |
| | 1986 | trash_block.is_coerce_result_ptr = true; |
| 1974 | defer trash_block.instructions.deinit(sema.gpa); | 1987 | defer trash_block.instructions.deinit(sema.gpa); |
| 1975 | | 1988 | |
| 1976 | const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr)); | 1989 | const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr)); |
| ... | @@ -10453,8 +10466,9 @@ fn analyzeArithmetic( | ... | @@ -10453,8 +10466,9 @@ fn analyzeArithmetic( |
| 10453 | if (maybe_rhs_val) |rhs_val| { | 10466 | if (maybe_rhs_val) |rhs_val| { |
| 10454 | if (is_int) { | 10467 | if (is_int) { |
| 10455 | const sum = try sema.intAdd(block, src, lhs_val, rhs_val, resolved_type); | 10468 | const sum = try sema.intAdd(block, src, lhs_val, rhs_val, resolved_type); |
| 10456 | if (!(try sema.intFitsInType(block, src, sum, resolved_type))) { | 10469 | var vector_index: usize = undefined; |
| 10457 | return sema.failWithIntegerOverflow(block, src, resolved_type, sum); | 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 | return sema.addConstant(resolved_type, sum); | 10473 | return sema.addConstant(resolved_type, sum); |
| 10460 | } else { | 10474 | } else { |
| ... | @@ -10547,8 +10561,9 @@ fn analyzeArithmetic( | ... | @@ -10547,8 +10561,9 @@ fn analyzeArithmetic( |
| 10547 | if (maybe_rhs_val) |rhs_val| { | 10561 | if (maybe_rhs_val) |rhs_val| { |
| 10548 | if (is_int) { | 10562 | if (is_int) { |
| 10549 | const diff = try sema.intSub(block, src, lhs_val, rhs_val, resolved_type); | 10563 | const diff = try sema.intSub(block, src, lhs_val, rhs_val, resolved_type); |
| 10550 | if (!(try sema.intFitsInType(block, src, diff, resolved_type))) { | 10564 | var vector_index: usize = undefined; |
| 10551 | return sema.failWithIntegerOverflow(block, src, resolved_type, diff); | 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 | return sema.addConstant(resolved_type, diff); | 10568 | return sema.addConstant(resolved_type, diff); |
| 10554 | } else { | 10569 | } else { |
| ... | @@ -10921,8 +10936,9 @@ fn analyzeArithmetic( | ... | @@ -10921,8 +10936,9 @@ fn analyzeArithmetic( |
| 10921 | } | 10936 | } |
| 10922 | if (is_int) { | 10937 | if (is_int) { |
| 10923 | const product = try lhs_val.intMul(rhs_val, resolved_type, sema.arena, target); | 10938 | const product = try lhs_val.intMul(rhs_val, resolved_type, sema.arena, target); |
| 10924 | if (!(try sema.intFitsInType(block, src, product, resolved_type))) { | 10939 | var vector_index: usize = undefined; |
| 10925 | return sema.failWithIntegerOverflow(block, src, resolved_type, product); | 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 | return sema.addConstant(resolved_type, product); | 10943 | return sema.addConstant(resolved_type, product); |
| 10928 | } else { | 10944 | } else { |
| ... | @@ -16456,15 +16472,15 @@ fn analyzeShuffle( | ... | @@ -16456,15 +16472,15 @@ fn analyzeShuffle( |
| 16456 | } | 16472 | } |
| 16457 | if (unsigned >= operand_info[chosen][0]) { | 16473 | if (unsigned >= operand_info[chosen][0]) { |
| 16458 | const msg = msg: { | 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 | errdefer msg.destroy(sema.gpa); | 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 | unsigned, | 16479 | unsigned, |
| 16464 | operand_info[chosen][2].fmt(sema.mod), | 16480 | operand_info[chosen][2].fmt(sema.mod), |
| 16465 | }); | 16481 | }); |
| 16466 | | 16482 | |
| 16467 | if (chosen == 1) { | 16483 | if (chosen == 0) { |
| 16468 | try sema.errNote(block, b_src, msg, "selections from the second vector are specified with negative numbers", .{}); | 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,7 +17766,7 @@ fn zirBuiltinExtern( |
| 17750 | } | 17766 | } |
| 17751 | | 17767 | |
| 17752 | fn requireFunctionBlock(sema: *Sema, block: *Block, src: LazySrcLoc) !void { | 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 | return sema.fail(block, src, "instruction illegal outside function body", .{}); | 17770 | return sema.fail(block, src, "instruction illegal outside function body", .{}); |
| 17755 | } | 17771 | } |
| 17756 | } | 17772 | } |
| ... | @@ -19881,7 +19897,7 @@ fn coerce( | ... | @@ -19881,7 +19897,7 @@ fn coerce( |
| 19881 | .Int, .ComptimeInt => { | 19897 | .Int, .ComptimeInt => { |
| 19882 | if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| { | 19898 | if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| { |
| 19883 | // comptime known integer to other number | 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 | return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) }); | 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 | return try sema.addConstant(dest_ty, val); | 19903 | return try sema.addConstant(dest_ty, val); |
| ... | @@ -25829,7 +25845,7 @@ fn floatToIntScalar( | ... | @@ -25829,7 +25845,7 @@ fn floatToIntScalar( |
| 25829 | else | 25845 | else |
| 25830 | try Value.Tag.int_big_positive.create(sema.arena, result_limbs); | 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 | return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{ | 25849 | return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{ |
| 25834 | val.fmtValue(float_ty, sema.mod), int_ty.fmt(sema.mod), | 25850 | val.fmtValue(float_ty, sema.mod), int_ty.fmt(sema.mod), |
| 25835 | }); | 25851 | }); |
| ... | @@ -25845,6 +25861,7 @@ fn intFitsInType( | ... | @@ -25845,6 +25861,7 @@ fn intFitsInType( |
| 25845 | src: LazySrcLoc, | 25861 | src: LazySrcLoc, |
| 25846 | self: Value, | 25862 | self: Value, |
| 25847 | ty: Type, | 25863 | ty: Type, |
| | 25864 | vector_index: ?*usize, |
| 25848 | ) CompileError!bool { | 25865 | ) CompileError!bool { |
| 25849 | const target = sema.mod.getTarget(); | 25866 | const target = sema.mod.getTarget(); |
| 25850 | switch (self.tag()) { | 25867 | switch (self.tag()) { |
| ... | @@ -25954,8 +25971,9 @@ fn intFitsInType( | ... | @@ -25954,8 +25971,9 @@ fn intFitsInType( |
| 25954 | | 25971 | |
| 25955 | .aggregate => { | 25972 | .aggregate => { |
| 25956 | assert(ty.zigTypeTag() == .Vector); | 25973 | assert(ty.zigTypeTag() == .Vector); |
| 25957 | for (self.castTag(.aggregate).?.data) |elem| { | 25974 | for (self.castTag(.aggregate).?.data) |elem, i| { |
| 25958 | if (!(try sema.intFitsInType(block, src, elem, ty.scalarType()))) { | 25975 | if (!(try sema.intFitsInType(block, src, elem, ty.scalarType(), null))) { |
| | 25976 | if (vector_index) |some| some.* = i; |
| 25959 | return false; | 25977 | return false; |
| 25960 | } | 25978 | } |
| 25961 | } | 25979 | } |
| ... | @@ -25993,7 +26011,7 @@ fn enumHasInt( | ... | @@ -25993,7 +26011,7 @@ fn enumHasInt( |
| 25993 | int: Value, | 26011 | int: Value, |
| 25994 | ) CompileError!bool { | 26012 | ) CompileError!bool { |
| 25995 | switch (ty.tag()) { | 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 | .enum_full => { | 26015 | .enum_full => { |
| 25998 | const enum_full = ty.castTag(.enum_full).?.data; | 26016 | const enum_full = ty.castTag(.enum_full).?.data; |
| 25999 | const tag_ty = enum_full.tag_ty; | 26017 | const tag_ty = enum_full.tag_ty; |