| author | |
| committer | |
| log | c64279b15b527749420e0e79fcc6dbfbfeb02812 |
| tree | 8f7fe813a6b2b7048468731f5f93619b3704e882 |
| parent | 1adb15098c711973d1c75061f122b907aaf09a7c |
7 files changed, 89 insertions(+), 65 deletions(-)
src/Sema.zig+49-6| ... | ... | @@ -6398,7 +6398,6 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 6398 | 6398 | defer tracy.end(); |
| 6399 | 6399 | |
| 6400 | 6400 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 6401 | const src = inst_data.src(); | |
| 6402 | 6401 | const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 6403 | 6402 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 6404 | 6403 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| ... | ... | @@ -6406,16 +6405,29 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 6406 | 6405 | const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs); |
| 6407 | 6406 | const operand = sema.resolveInst(extra.rhs); |
| 6408 | 6407 | |
| 6408 | return sema.intCast(block, dest_ty, dest_ty_src, operand, operand_src, true); | |
| 6409 | } | |
| 6410 | ||
| 6411 | fn intCast( | |
| 6412 | sema: *Sema, | |
| 6413 | block: *Block, | |
| 6414 | dest_ty: Type, | |
| 6415 | dest_ty_src: LazySrcLoc, | |
| 6416 | operand: Air.Inst.Ref, | |
| 6417 | operand_src: LazySrcLoc, | |
| 6418 | runtime_safety: bool, | |
| 6419 | ) CompileError!Air.Inst.Ref { | |
| 6409 | 6420 | const dest_is_comptime_int = try sema.checkIntType(block, dest_ty_src, dest_ty); |
| 6410 | 6421 | _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand)); |
| 6411 | 6422 | |
| 6412 | 6423 | if (try sema.isComptimeKnown(block, operand_src, operand)) { |
| 6413 | 6424 | return sema.coerce(block, dest_ty, operand, operand_src); |
| 6414 | 6425 | } else if (dest_is_comptime_int) { |
| 6415 | return sema.fail(block, src, "unable to cast runtime value to 'comptime_int'", .{}); | |
| 6426 | return sema.fail(block, operand_src, "unable to cast runtime value to 'comptime_int'", .{}); | |
| 6416 | 6427 | } |
| 6417 | 6428 | |
| 6418 | 6429 | // TODO insert safety check to make sure the value fits in the dest type |
| 6430 | _ = runtime_safety; | |
| 6419 | 6431 | |
| 6420 | 6432 | if ((try sema.typeHasOnePossibleValue(block, dest_ty_src, dest_ty))) |opv| { |
| 6421 | 6433 | return sema.addConstant(dest_ty, opv); |
| ... | ... | @@ -7986,6 +7998,7 @@ fn zirShl( |
| 7986 | 7998 | const rhs = sema.resolveInst(extra.rhs); |
| 7987 | 7999 | |
| 7988 | 8000 | // TODO coerce rhs if air_tag is not shl_sat |
| 8001 | const rhs_is_comptime_int = try sema.checkIntType(block, rhs_src, sema.typeOf(rhs)); | |
| 7989 | 8002 | |
| 7990 | 8003 | const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs); |
| 7991 | 8004 | const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, rhs); |
| ... | ... | @@ -7999,13 +8012,14 @@ fn zirShl( |
| 7999 | 8012 | } |
| 8000 | 8013 | } |
| 8001 | 8014 | |
| 8002 | const runtime_src = if (maybe_lhs_val) |lhs_val| rs: { | |
| 8003 | const lhs_ty = sema.typeOf(lhs); | |
| 8015 | const lhs_ty = sema.typeOf(lhs); | |
| 8016 | const rhs_ty = sema.typeOf(rhs); | |
| 8017 | const target = sema.mod.getTarget(); | |
| 8004 | 8018 | |
| 8019 | const runtime_src = if (maybe_lhs_val) |lhs_val| rs: { | |
| 8005 | 8020 | if (lhs_val.isUndef()) return sema.addConstUndef(lhs_ty); |
| 8006 | 8021 | const rhs_val = maybe_rhs_val orelse break :rs rhs_src; |
| 8007 | 8022 | |
| 8008 | const target = sema.mod.getTarget(); | |
| 8009 | 8023 | const val = switch (air_tag) { |
| 8010 | 8024 | .shl_exact => val: { |
| 8011 | 8025 | const shifted = try lhs_val.shl(rhs_val, sema.arena); |
| ... | ... | @@ -8038,8 +8052,24 @@ fn zirShl( |
| 8038 | 8052 | |
| 8039 | 8053 | // TODO: insert runtime safety check for shl_exact |
| 8040 | 8054 | |
| 8055 | const new_rhs = if (air_tag == .shl_sat) rhs: { | |
| 8056 | // Limit the RHS type for saturating shl to be an integer as small as the LHS. | |
| 8057 | if (rhs_is_comptime_int or | |
| 8058 | rhs_ty.intInfo(target).bits > lhs_ty.intInfo(target).bits) | |
| 8059 | { | |
| 8060 | const max_int = try sema.addConstant( | |
| 8061 | lhs_ty, | |
| 8062 | try lhs_ty.maxInt(sema.arena, target), | |
| 8063 | ); | |
| 8064 | const rhs_limited = try sema.analyzeMinMax(block, rhs_src, rhs, max_int, .min, rhs_src, rhs_src); | |
| 8065 | break :rhs try sema.intCast(block, lhs_ty, rhs_src, rhs_limited, rhs_src, false); | |
| 8066 | } else { | |
| 8067 | break :rhs rhs; | |
| 8068 | } | |
| 8069 | } else rhs; | |
| 8070 | ||
| 8041 | 8071 | try sema.requireRuntimeBlock(block, runtime_src); |
| 8042 | return block.addBinOp(air_tag, lhs, rhs); | |
| 8072 | return block.addBinOp(air_tag, lhs, new_rhs); | |
| 8043 | 8073 | } |
| 8044 | 8074 | |
| 8045 | 8075 | fn zirShr( |
| ... | ... | @@ -14537,6 +14567,19 @@ fn zirMinMax( |
| 14537 | 14567 | const rhs = sema.resolveInst(extra.rhs); |
| 14538 | 14568 | try sema.checkNumericType(block, lhs_src, sema.typeOf(lhs)); |
| 14539 | 14569 | try sema.checkNumericType(block, rhs_src, sema.typeOf(rhs)); |
| 14570 | return sema.analyzeMinMax(block, src, lhs, rhs, air_tag, lhs_src, rhs_src); | |
| 14571 | } | |
| 14572 | ||
| 14573 | fn analyzeMinMax( | |
| 14574 | sema: *Sema, | |
| 14575 | block: *Block, | |
| 14576 | src: LazySrcLoc, | |
| 14577 | lhs: Air.Inst.Ref, | |
| 14578 | rhs: Air.Inst.Ref, | |
| 14579 | air_tag: Air.Inst.Tag, | |
| 14580 | lhs_src: LazySrcLoc, | |
| 14581 | rhs_src: LazySrcLoc, | |
| 14582 | ) CompileError!Air.Inst.Ref { | |
| 14540 | 14583 | const simd_op = try sema.checkSimdBinOp(block, src, lhs, rhs, lhs_src, rhs_src); |
| 14541 | 14584 | |
| 14542 | 14585 | // TODO @maximum(max_int, undefined) should return max_int |
test/behavior/floatop.zig+9-2| ... | ... | @@ -609,7 +609,11 @@ test "negation f64" { |
| 609 | 609 | } |
| 610 | 610 | |
| 611 | 611 | test "negation f80" { |
| 612 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 612 | if (builtin.zig_backend != .stage1) { | |
| 613 | // This test case exercises @intToFloat f80 in the compiler implementation. | |
| 614 | // https://github.com/ziglang/zig/issues/11030 | |
| 615 | return error.SkipZigTest; | |
| 616 | } | |
| 613 | 617 | |
| 614 | 618 | if (builtin.os.tag == .freebsd) { |
| 615 | 619 | // TODO file issue to track this failure |
| ... | ... | @@ -673,7 +677,10 @@ fn fnWithFloatMode() f32 { |
| 673 | 677 | } |
| 674 | 678 | |
| 675 | 679 | test "float literal at compile time not lossy" { |
| 676 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 680 | if (builtin.zig_backend != .stage1) { | |
| 681 | // https://github.com/ziglang/zig/issues/11169 | |
| 682 | return error.SkipZigTest; | |
| 683 | } | |
| 677 | 684 | |
| 678 | 685 | try expect(16777216.0 + 1.0 == 16777217.0); |
| 679 | 686 | try expect(9007199254740992.0 + 1.0 == 9007199254740993.0); |
test/behavior/fn.zig+16-7| ... | ... | @@ -307,13 +307,20 @@ fn acceptsString(foo: []u8) void { |
| 307 | 307 | } |
| 308 | 308 | |
| 309 | 309 | test "function pointers" { |
| 310 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 310 | if (builtin.zig_backend == .stage1) { | |
| 311 | // stage1 has wrong semantics for function pointers | |
| 312 | return error.SkipZigTest; | |
| 313 | } | |
| 314 | ||
| 315 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 316 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 317 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 311 | 318 | |
| 312 | const fns = [_]@TypeOf(fn1){ | |
| 313 | fn1, | |
| 314 | fn2, | |
| 315 | fn3, | |
| 316 | fn4, | |
| 319 | const fns = [_]*const @TypeOf(fn1){ | |
| 320 | &fn1, | |
| 321 | &fn2, | |
| 322 | &fn3, | |
| 323 | &fn4, | |
| 317 | 324 | }; |
| 318 | 325 | for (fns) |f, i| { |
| 319 | 326 | try expect(f() == @intCast(u32, i) + 5); |
| ... | ... | @@ -380,7 +387,9 @@ test "ability to give comptime types and non comptime types to same parameter" { |
| 380 | 387 | } |
| 381 | 388 | |
| 382 | 389 | test "function with inferred error set but returning no error" { |
| 383 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 390 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 391 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 392 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 384 | 393 | |
| 385 | 394 | const S = struct { |
| 386 | 395 | fn foo() !void {} |
test/behavior/saturating_arithmetic.zig-2| ... | ... | @@ -163,8 +163,6 @@ test "saturating shift-left" { |
| 163 | 163 | } |
| 164 | 164 | |
| 165 | 165 | test "saturating shl uses the LHS type" { |
| 166 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 167 | ||
| 168 | 166 | const lhs_const: u8 = 1; |
| 169 | 167 | var lhs_var: u8 = 1; |
| 170 | 168 |
test/behavior/translate_c_macros.zig+3-3| ... | ... | @@ -45,16 +45,16 @@ test "cast negative integer to pointer" { |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | 47 | test "casting to union with a macro" { |
| 48 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO Sema.zirUnionInitPtr | |
| 48 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 49 | 49 | |
| 50 | 50 | const l: c_long = 42; |
| 51 | 51 | const d: f64 = 2.0; |
| 52 | 52 | |
| 53 | 53 | var casted = h.UNION_CAST(l); |
| 54 | try expectEqual(l, casted.l); | |
| 54 | try expect(l == casted.l); | |
| 55 | 55 | |
| 56 | 56 | casted = h.UNION_CAST(d); |
| 57 | try expectEqual(d, casted.d); | |
| 57 | try expect(d == casted.d); | |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | test "nested comma operator" { |
test/behavior/type.zig+4-37| ... | ... | @@ -230,7 +230,10 @@ test "Type.Vector" { |
| 230 | 230 | } |
| 231 | 231 | |
| 232 | 232 | test "Type.AnyFrame" { |
| 233 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 233 | if (builtin.zig_backend != .stage1) { | |
| 234 | // https://github.com/ziglang/zig/issues/6025 | |
| 235 | return error.SkipZigTest; | |
| 236 | } | |
| 234 | 237 | |
| 235 | 238 | try testTypes(&[_]type{ |
| 236 | 239 | anyframe, |
| ... | ... | @@ -514,39 +517,3 @@ test "Type.Union from regular enum" { |
| 514 | 517 | _ = T; |
| 515 | 518 | _ = @typeInfo(T).Union; |
| 516 | 519 | } |
| 517 | ||
| 518 | test "Type.Fn" { | |
| 519 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 520 | ||
| 521 | // wasm doesn't support align attributes on functions | |
| 522 | if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest; | |
| 523 | ||
| 524 | const foo = struct { | |
| 525 | fn func(a: usize, b: bool) align(4) callconv(.C) usize { | |
| 526 | _ = a; | |
| 527 | _ = b; | |
| 528 | return 0; | |
| 529 | } | |
| 530 | }.func; | |
| 531 | const Foo = @Type(@typeInfo(@TypeOf(foo))); | |
| 532 | const foo_2: Foo = foo; | |
| 533 | _ = foo_2; | |
| 534 | } | |
| 535 | ||
| 536 | test "Type.BoundFn" { | |
| 537 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 538 | ||
| 539 | // wasm doesn't support align attributes on functions | |
| 540 | if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest; | |
| 541 | ||
| 542 | const TestStruct = packed struct { | |
| 543 | pub fn foo(self: *const @This()) align(4) callconv(.Unspecified) void { | |
| 544 | _ = self; | |
| 545 | } | |
| 546 | }; | |
| 547 | const test_instance: TestStruct = undefined; | |
| 548 | try testing.expect(std.meta.eql( | |
| 549 | @typeName(@TypeOf(test_instance.foo)), | |
| 550 | @typeName(@Type(@typeInfo(@TypeOf(test_instance.foo)))), | |
| 551 | )); | |
| 552 | } |
test/behavior/type_info.zig+8-8| ... | ... | @@ -379,12 +379,6 @@ fn testFunction() !void { |
| 379 | 379 | try expect(fn_info.Fn.return_type.? == usize); |
| 380 | 380 | const fn_aligned_info = @typeInfo(@TypeOf(fooAligned)); |
| 381 | 381 | try expect(fn_aligned_info.Fn.alignment == 4); |
| 382 | ||
| 383 | if (builtin.zig_backend != .stage1) return; // no bound fn in stage2 | |
| 384 | const test_instance: TestPackedStruct = undefined; | |
| 385 | const bound_fn_info = @typeInfo(@TypeOf(test_instance.foo)); | |
| 386 | try expect(bound_fn_info == .BoundFn); | |
| 387 | try expect(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestPackedStruct); | |
| 388 | 382 | } |
| 389 | 383 | |
| 390 | 384 | extern fn foo(a: usize, b: bool, ...) callconv(.C) usize; |
| ... | ... | @@ -413,7 +407,10 @@ fn testVector() !void { |
| 413 | 407 | } |
| 414 | 408 | |
| 415 | 409 | test "type info: anyframe and anyframe->T" { |
| 416 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 410 | if (builtin.zig_backend != .stage1) { | |
| 411 | // https://github.com/ziglang/zig/issues/6025 | |
| 412 | return error.SkipZigTest; | |
| 413 | } | |
| 417 | 414 | |
| 418 | 415 | try testAnyFrame(); |
| 419 | 416 | comptime try testAnyFrame(); |
| ... | ... | @@ -469,7 +466,10 @@ fn add(a: i32, b: i32) i32 { |
| 469 | 466 | } |
| 470 | 467 | |
| 471 | 468 | test "type info for async frames" { |
| 472 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 469 | if (builtin.zig_backend != .stage1) { | |
| 470 | // https://github.com/ziglang/zig/issues/6025 | |
| 471 | return error.SkipZigTest; | |
| 472 | } | |
| 473 | 473 | |
| 474 | 474 | switch (@typeInfo(@Frame(add))) { |
| 475 | 475 | .Frame => |frame| { |