| author | |
| committer | |
| log | 16cc65242fd6e2fc9883fb87e5e78e1d1641db3e |
| tree | 93a82a9b42856d0e54aaf45889ee9670a14c9571 |
| parent | 400319872ba2fd1707a90db232e9c790450f37eb |
| parent | 02d7292a8c1f478b77ef23dbe875b5443bba951c |
| signature |
std.math: fix behavior relating to comptime_int arguments5 files changed, 65 insertions(+), 6 deletions(-)
build.zig+14| ... | ... | @@ -554,6 +554,8 @@ fn addCmakeCfgOptionsToExe( |
| 554 | 554 | }) catch unreachable); |
| 555 | 555 | assert(cfg.lld_include_dir.len != 0); |
| 556 | 556 | exe.addIncludePath(cfg.lld_include_dir); |
| 557 | exe.addIncludePath(cfg.llvm_include_dir); | |
| 558 | exe.addLibraryPath(cfg.llvm_lib_dir); | |
| 557 | 559 | addCMakeLibraryList(exe, cfg.clang_libraries); |
| 558 | 560 | addCMakeLibraryList(exe, cfg.lld_libraries); |
| 559 | 561 | addCMakeLibraryList(exe, cfg.llvm_libraries); |
| ... | ... | @@ -684,6 +686,8 @@ const CMakeConfig = struct { |
| 684 | 686 | lld_include_dir: []const u8, |
| 685 | 687 | lld_libraries: []const u8, |
| 686 | 688 | clang_libraries: []const u8, |
| 689 | llvm_lib_dir: []const u8, | |
| 690 | llvm_include_dir: []const u8, | |
| 687 | 691 | llvm_libraries: []const u8, |
| 688 | 692 | dia_guids_lib: []const u8, |
| 689 | 693 | }; |
| ... | ... | @@ -745,6 +749,8 @@ fn parseConfigH(b: *Builder, config_h_text: []const u8) ?CMakeConfig { |
| 745 | 749 | .lld_include_dir = undefined, |
| 746 | 750 | .lld_libraries = undefined, |
| 747 | 751 | .clang_libraries = undefined, |
| 752 | .llvm_lib_dir = undefined, | |
| 753 | .llvm_include_dir = undefined, | |
| 748 | 754 | .llvm_libraries = undefined, |
| 749 | 755 | .dia_guids_lib = undefined, |
| 750 | 756 | }; |
| ... | ... | @@ -782,6 +788,14 @@ fn parseConfigH(b: *Builder, config_h_text: []const u8) ?CMakeConfig { |
| 782 | 788 | .prefix = "#define ZIG_DIA_GUIDS_LIB ", |
| 783 | 789 | .field = "dia_guids_lib", |
| 784 | 790 | }, |
| 791 | .{ | |
| 792 | .prefix = "#define ZIG_LLVM_INCLUDE_PATH ", | |
| 793 | .field = "llvm_include_dir", | |
| 794 | }, | |
| 795 | .{ | |
| 796 | .prefix = "#define ZIG_LLVM_LIB_PATH ", | |
| 797 | .field = "llvm_lib_dir", | |
| 798 | }, | |
| 785 | 799 | // .prefix = ZIG_LLVM_LINK_MODE parsed manually below |
| 786 | 800 | }; |
| 787 | 801 |
lib/std/math.zig+10-3| ... | ... | @@ -1063,10 +1063,11 @@ test "negateCast" { |
| 1063 | 1063 | /// return null. |
| 1064 | 1064 | pub fn cast(comptime T: type, x: anytype) ?T { |
| 1065 | 1065 | comptime assert(@typeInfo(T) == .Int); // must pass an integer |
| 1066 | comptime assert(@typeInfo(@TypeOf(x)) == .Int); // must pass an integer | |
| 1067 | if (maxInt(@TypeOf(x)) > maxInt(T) and x > maxInt(T)) { | |
| 1066 | const is_comptime = @TypeOf(x) == comptime_int; | |
| 1067 | comptime assert(is_comptime or @typeInfo(@TypeOf(x)) == .Int); // must pass an integer | |
| 1068 | if ((is_comptime or maxInt(@TypeOf(x)) > maxInt(T)) and x > maxInt(T)) { | |
| 1068 | 1069 | return null; |
| 1069 | } else if (minInt(@TypeOf(x)) < minInt(T) and x < minInt(T)) { | |
| 1070 | } else if ((is_comptime or minInt(@TypeOf(x)) < minInt(T)) and x < minInt(T)) { | |
| 1070 | 1071 | return null; |
| 1071 | 1072 | } else { |
| 1072 | 1073 | return @intCast(T, x); |
| ... | ... | @@ -1074,12 +1075,18 @@ pub fn cast(comptime T: type, x: anytype) ?T { |
| 1074 | 1075 | } |
| 1075 | 1076 | |
| 1076 | 1077 | test "cast" { |
| 1078 | try testing.expect(cast(u8, 300) == null); | |
| 1077 | 1079 | try testing.expect(cast(u8, @as(u32, 300)) == null); |
| 1080 | try testing.expect(cast(i8, -200) == null); | |
| 1078 | 1081 | try testing.expect(cast(i8, @as(i32, -200)) == null); |
| 1082 | try testing.expect(cast(u8, -1) == null); | |
| 1079 | 1083 | try testing.expect(cast(u8, @as(i8, -1)) == null); |
| 1084 | try testing.expect(cast(u64, -1) == null); | |
| 1080 | 1085 | try testing.expect(cast(u64, @as(i8, -1)) == null); |
| 1081 | 1086 | |
| 1087 | try testing.expect(cast(u8, 255).? == @as(u8, 255)); | |
| 1082 | 1088 | try testing.expect(cast(u8, @as(u32, 255)).? == @as(u8, 255)); |
| 1089 | try testing.expect(@TypeOf(cast(u8, 255).?) == u8); | |
| 1083 | 1090 | try testing.expect(@TypeOf(cast(u8, @as(u32, 255)).?) == u8); |
| 1084 | 1091 | } |
| 1085 | 1092 |
lib/std/math/big/int.zig+27-2| ... | ... | @@ -21,6 +21,9 @@ const debug_safety = false; |
| 21 | 21 | |
| 22 | 22 | /// Returns the number of limbs needed to store `scalar`, which must be a |
| 23 | 23 | /// primitive integer value. |
| 24 | /// Note: A comptime-known upper bound of this value that may be used | |
| 25 | /// instead if `scalar` is not already comptime-known is | |
| 26 | /// `calcTwosCompLimbCount(@typeInfo(@TypeOf(scalar)).Int.bits)` | |
| 24 | 27 | pub fn calcLimbLen(scalar: anytype) usize { |
| 25 | 28 | if (scalar == 0) { |
| 26 | 29 | return 1; |
| ... | ... | @@ -391,7 +394,18 @@ pub const Mutable = struct { |
| 391 | 394 | /// Asserts the result fits in `r`. An upper bound on the number of limbs needed by |
| 392 | 395 | /// r is `math.max(a.limbs.len, calcLimbLen(scalar)) + 1`. |
| 393 | 396 | pub fn addScalar(r: *Mutable, a: Const, scalar: anytype) void { |
| 394 | var limbs: [calcLimbLen(scalar)]Limb = undefined; | |
| 397 | // Normally we could just determine the number of limbs needed with calcLimbLen, | |
| 398 | // but that is not comptime-known when scalar is not a comptime_int. Instead, we | |
| 399 | // use calcTwosCompLimbCount for a non-comptime_int scalar, which can be pessimistic | |
| 400 | // in the case that scalar happens to be small in magnitude within its type, but it | |
| 401 | // is well worth being able to use the stack and not needing an allocator passed in. | |
| 402 | // Note that Mutable.init still sets len to calcLimbLen(scalar) in any case. | |
| 403 | const limb_len = comptime switch (@typeInfo(@TypeOf(scalar))) { | |
| 404 | .ComptimeInt => calcLimbLen(scalar), | |
| 405 | .Int => |info| calcTwosCompLimbCount(info.bits), | |
| 406 | else => @compileError("expected scalar to be an int"), | |
| 407 | }; | |
| 408 | var limbs: [limb_len]Limb = undefined; | |
| 395 | 409 | const operand = init(&limbs, scalar).toConst(); |
| 396 | 410 | return add(r, a, operand); |
| 397 | 411 | } |
| ... | ... | @@ -2303,7 +2317,18 @@ pub const Const = struct { |
| 2303 | 2317 | |
| 2304 | 2318 | /// Same as `order` but the right-hand operand is a primitive integer. |
| 2305 | 2319 | pub fn orderAgainstScalar(lhs: Const, scalar: anytype) math.Order { |
| 2306 | var limbs: [calcLimbLen(scalar)]Limb = undefined; | |
| 2320 | // Normally we could just determine the number of limbs needed with calcLimbLen, | |
| 2321 | // but that is not comptime-known when scalar is not a comptime_int. Instead, we | |
| 2322 | // use calcTwosCompLimbCount for a non-comptime_int scalar, which can be pessimistic | |
| 2323 | // in the case that scalar happens to be small in magnitude within its type, but it | |
| 2324 | // is well worth being able to use the stack and not needing an allocator passed in. | |
| 2325 | // Note that Mutable.init still sets len to calcLimbLen(scalar) in any case. | |
| 2326 | const limb_len = comptime switch (@typeInfo(@TypeOf(scalar))) { | |
| 2327 | .ComptimeInt => calcLimbLen(scalar), | |
| 2328 | .Int => |info| calcTwosCompLimbCount(info.bits), | |
| 2329 | else => @compileError("expected scalar to be an int"), | |
| 2330 | }; | |
| 2331 | var limbs: [limb_len]Limb = undefined; | |
| 2307 | 2332 | const rhs = Mutable.init(&limbs, scalar); |
| 2308 | 2333 | return order(lhs, rhs.toConst()); |
| 2309 | 2334 | } |
lib/std/math/big/int_test.zig+12-1| ... | ... | @@ -573,7 +573,7 @@ test "big.int add sign" { |
| 573 | 573 | try testing.expect((try a.to(i32)) == -3); |
| 574 | 574 | } |
| 575 | 575 | |
| 576 | test "big.int add scalar" { | |
| 576 | test "big.int add comptime scalar" { | |
| 577 | 577 | var a = try Managed.initSet(testing.allocator, 50); |
| 578 | 578 | defer a.deinit(); |
| 579 | 579 | |
| ... | ... | @@ -584,6 +584,17 @@ test "big.int add scalar" { |
| 584 | 584 | try testing.expect((try b.to(u32)) == 55); |
| 585 | 585 | } |
| 586 | 586 | |
| 587 | test "big.int add scalar" { | |
| 588 | var a = try Managed.initSet(testing.allocator, 123); | |
| 589 | defer a.deinit(); | |
| 590 | ||
| 591 | var b = try Managed.init(testing.allocator); | |
| 592 | defer b.deinit(); | |
| 593 | try b.addScalar(&a, @as(u32, 31)); | |
| 594 | ||
| 595 | try testing.expect((try b.to(u32)) == 154); | |
| 596 | } | |
| 597 | ||
| 587 | 598 | test "big.int addWrap single-single, unsigned" { |
| 588 | 599 | var a = try Managed.initSet(testing.allocator, maxInt(u17)); |
| 589 | 600 | defer a.deinit(); |
src/stage1/config.h.in+2| ... | ... | @@ -22,6 +22,8 @@ |
| 22 | 22 | #define ZIG_LLD_INCLUDE_PATH "@LLD_INCLUDE_DIRS@" |
| 23 | 23 | #define ZIG_LLD_LIBRARIES "@LLD_LIBRARIES@" |
| 24 | 24 | #define ZIG_CLANG_LIBRARIES "@CLANG_LIBRARIES@" |
| 25 | #define ZIG_LLVM_INCLUDE_PATH "@LLVM_INCLUDE_DIRS@" | |
| 26 | #define ZIG_LLVM_LIB_PATH "@LLVM_LIBDIRS@" | |
| 25 | 27 | #define ZIG_LLVM_LIBRARIES "@LLVM_LIBRARIES@" |
| 26 | 28 | #define ZIG_DIA_GUIDS_LIB "@ZIG_DIA_GUIDS_LIB_ESCAPED@" |
| 27 | 29 |