authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-27 22:03:12-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:56-07:00
logd40b83de45db27c8c3e7a1f2ccf892563df43637
treec5be27004a8a8718571f2d1ff9d08e7e3f6c2904
parent2d5bc0146941f4cc207c4fd23058e25a16fd40a7

behavior: pass more tests on llvm again


6 files changed, 208 insertions(+), 119 deletions(-)

src/InternPool.zig+34-13
......@@ -4250,6 +4250,8 @@ pub fn sliceLen(ip: InternPool, i: Index) Index {
42504250/// * int <=> enum
42514251/// * enum_literal => enum
42524252/// * ptr <=> ptr
4253/// * opt ptr <=> ptr
4254/// * opt ptr <=> opt ptr
42534255/// * int => ptr
42544256/// * null_value => opt
42554257/// * payload => opt
......@@ -4258,9 +4260,6 @@ pub fn sliceLen(ip: InternPool, i: Index) Index {
42584260/// * error set => error union
42594261/// * payload => error union
42604262/// * fn <=> fn
4261/// * array <=> array
4262/// * array <=> vector
4263/// * vector <=> vector
42644263pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {
42654264 const old_ty = ip.typeOf(val);
42664265 if (old_ty == new_ty) return val;
......@@ -4270,6 +4269,15 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
42704269 return ip.get(gpa, .{ .opt = .{
42714270 .ty = new_ty,
42724271 .val = .none,
4272 } })
4273 else if (ip.isPointerType(new_ty))
4274 return ip.get(gpa, .{ .ptr = .{
4275 .ty = new_ty,
4276 .addr = .{ .int = .zero_usize },
4277 .len = switch (ip.indexToKey(new_ty).ptr_type.size) {
4278 .One, .Many, .C => .none,
4279 .Slice => try ip.get(gpa, .{ .undef = .usize_type }),
4280 },
42734281 } }),
42744282 else => switch (ip.indexToKey(val)) {
42754283 .undef => return ip.get(gpa, .{ .undef = new_ty }),
......@@ -4320,6 +4328,18 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
43204328 .addr = ptr.addr,
43214329 .len = ptr.len,
43224330 } }),
4331 .opt => |opt| if (ip.isPointerType(new_ty))
4332 return switch (opt.val) {
4333 .none => try ip.get(gpa, .{ .ptr = .{
4334 .ty = new_ty,
4335 .addr = .{ .int = .zero_usize },
4336 .len = switch (ip.indexToKey(new_ty).ptr_type.size) {
4337 .One, .Many, .C => .none,
4338 .Slice => try ip.get(gpa, .{ .undef = .usize_type }),
4339 },
4340 } }),
4341 else => try ip.getCoerced(gpa, opt.val, new_ty),
4342 },
43234343 .err => |err| if (ip.isErrorSetType(new_ty))
43244344 return ip.get(gpa, .{ .err = .{
43254345 .ty = new_ty,
......@@ -4335,14 +4355,6 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
43354355 .ty = new_ty,
43364356 .val = error_union.val,
43374357 } }),
4338 .aggregate => |aggregate| return ip.get(gpa, .{ .aggregate = .{
4339 .ty = new_ty,
4340 .storage = switch (aggregate.storage) {
4341 .bytes => |bytes| .{ .bytes = bytes[0..@intCast(usize, ip.aggregateTypeLen(new_ty))] },
4342 .elems => |elems| .{ .elems = elems[0..@intCast(usize, ip.aggregateTypeLen(new_ty))] },
4343 .repeated_elem => |elem| .{ .repeated_elem = elem },
4344 },
4345 } }),
43464358 else => {},
43474359 },
43484360 }
......@@ -4364,8 +4376,10 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
43644376 else => {},
43654377 }
43664378 if (std.debug.runtime_safety) {
4367 std.debug.panic("val={any} new_ty={any}\n", .{
4368 ip.items.get(@enumToInt(val)), ip.items.get(@enumToInt(new_ty)),
4379 std.debug.panic("InternPool.getCoerced of {s} not implemented from {s} to {s}", .{
4380 @tagName(ip.indexToKey(val)),
4381 @tagName(ip.indexToKey(old_ty)),
4382 @tagName(ip.indexToKey(new_ty)),
43694383 });
43704384 }
43714385 unreachable;
......@@ -4507,6 +4521,13 @@ pub fn isErrorUnionType(ip: InternPool, ty: Index) bool {
45074521 return ip.indexToKey(ty) == .error_union_type;
45084522}
45094523
4524pub fn isAggregateType(ip: InternPool, ty: Index) bool {
4525 return switch (ip.indexToKey(ty)) {
4526 .array_wype, .vector_type, .anon_struct_type, .struct_type => true,
4527 else => false,
4528 };
4529}
4530
45104531/// The is only legal because the initializer is not part of the hash.
45114532pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {
45124533 assert(ip.items.items(.tag)[@enumToInt(index)] == .variable);
src/Sema.zig+148-89
......@@ -6381,8 +6381,7 @@ fn zirCall(
63816381 var input_is_error = false;
63826382 const block_index = @intCast(Air.Inst.Index, block.instructions.items.len);
63836383
6384 const func_ty_info = mod.typeToFunc(func_ty).?;
6385 const fn_params_len = func_ty_info.param_types.len;
6384 const fn_params_len = mod.typeToFunc(func_ty).?.param_types.len;
63866385 const parent_comptime = block.is_comptime;
63876386 // `extra_index` and `arg_index` are separate since the bound function is passed as the first argument.
63886387 var extra_index: usize = 0;
......@@ -6391,6 +6390,7 @@ fn zirCall(
63916390 extra_index += 1;
63926391 arg_index += 1;
63936392 }) {
6393 const func_ty_info = mod.typeToFunc(func_ty).?;
63946394 const arg_end = sema.code.extra[extra.end + extra_index];
63956395 defer arg_start = arg_end;
63966396
......@@ -6876,7 +6876,11 @@ fn analyzeCall(
68766876 .args_count = @intCast(u32, func_ty_info.param_types.len),
68776877 };
68786878 var delete_memoized_call_key = false;
6879 defer if (delete_memoized_call_key) mod.memoized_call_args.shrinkRetainingCapacity(memoized_call_key.args_index);
6879 defer if (delete_memoized_call_key) {
6880 assert(mod.memoized_call_args.items.len >= memoized_call_key.args_index and
6881 mod.memoized_call_args.items.len < memoized_call_key.args_index + memoized_call_key.args_count);
6882 mod.memoized_call_args.shrinkRetainingCapacity(memoized_call_key.args_index);
6883 };
68806884 if (is_comptime_call) {
68816885 try mod.memoized_call_args.ensureUnusedCapacity(gpa, memoized_call_key.args_count);
68826886 delete_memoized_call_key = true;
......@@ -6990,14 +6994,22 @@ fn analyzeCall(
69906994 .{ .args = &mod.memoized_call_args },
69916995 );
69926996 if (gop.found_existing) {
6997 assert(mod.memoized_call_args.items.len == memoized_call_key.args_index + memoized_call_key.args_count);
6998 mod.memoized_call_args.shrinkRetainingCapacity(memoized_call_key.args_index);
6999 delete_memoized_call_key = false;
7000
69937001 // We need to use the original memoized error set instead of fn_ret_ty.
69947002 const result = gop.value_ptr.*;
69957003 assert(result != .none); // recursive memoization?
7004
69967005 break :res2 try sema.addConstant(mod.intern_pool.typeOf(result).toType(), result.toValue());
69977006 }
69987007 gop.value_ptr.* = .none;
6999 delete_memoized_call_key = false;
7008 } else if (delete_memoized_call_key) {
7009 assert(mod.memoized_call_args.items.len == memoized_call_key.args_index + memoized_call_key.args_count);
7010 mod.memoized_call_args.shrinkRetainingCapacity(memoized_call_key.args_index);
70007011 }
7012 delete_memoized_call_key = false;
70017013
70027014 const new_func_resolved_ty = try mod.funcType(new_fn_info);
70037015 if (!is_comptime_call and !block.is_typeof) {
......@@ -14324,13 +14336,14 @@ fn zirOverflowArithmetic(
1432414336 const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);
1432514337
1432614338 const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);
14339 const overflow_ty = mod.intern_pool.indexToKey(tuple_ty.toIntern()).anon_struct_type.types[1].toType();
1432714340
1432814341 var result: struct {
1432914342 inst: Air.Inst.Ref = .none,
1433014343 wrapped: Value = Value.@"unreachable",
1433114344 overflow_bit: Value,
1433214345 } = result: {
14333 const zero = try mod.intValue(dest_ty.scalarType(mod), 0);
14346 const zero_bit = try mod.intValue(Type.u1, 0);
1433414347 switch (zir_tag) {
1433514348 .add_with_overflow => {
1433614349 // If either of the arguments is zero, `false` is returned and the other is stored
......@@ -14338,12 +14351,12 @@ fn zirOverflowArithmetic(
1433814351 // Otherwise, if either of the argument is undefined, undefined is returned.
1433914352 if (maybe_lhs_val) |lhs_val| {
1434014353 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14341 break :result .{ .overflow_bit = try sema.splat(dest_ty, zero), .inst = rhs };
14354 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
1434214355 }
1434314356 }
1434414357 if (maybe_rhs_val) |rhs_val| {
1434514358 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14346 break :result .{ .overflow_bit = try sema.splat(dest_ty, zero), .inst = lhs };
14359 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
1434714360 }
1434814361 }
1434914362 if (maybe_lhs_val) |lhs_val| {
......@@ -14364,7 +14377,7 @@ fn zirOverflowArithmetic(
1436414377 if (rhs_val.isUndef(mod)) {
1436514378 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
1436614379 } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14367 break :result .{ .overflow_bit = try sema.splat(dest_ty, zero), .inst = lhs };
14380 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
1436814381 } else if (maybe_lhs_val) |lhs_val| {
1436914382 if (lhs_val.isUndef(mod)) {
1437014383 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
......@@ -14383,9 +14396,9 @@ fn zirOverflowArithmetic(
1438314396 if (maybe_lhs_val) |lhs_val| {
1438414397 if (!lhs_val.isUndef(mod)) {
1438514398 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14386 break :result .{ .overflow_bit = try sema.splat(dest_ty, zero), .inst = lhs };
14399 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
1438714400 } else if (try sema.compareAll(lhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {
14388 break :result .{ .overflow_bit = try sema.splat(dest_ty, zero), .inst = rhs };
14401 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
1438914402 }
1439014403 }
1439114404 }
......@@ -14393,9 +14406,9 @@ fn zirOverflowArithmetic(
1439314406 if (maybe_rhs_val) |rhs_val| {
1439414407 if (!rhs_val.isUndef(mod)) {
1439514408 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14396 break :result .{ .overflow_bit = try sema.splat(dest_ty, zero), .inst = rhs };
14409 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
1439714410 } else if (try sema.compareAll(rhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {
14398 break :result .{ .overflow_bit = try sema.splat(dest_ty, zero), .inst = lhs };
14411 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
1439914412 }
1440014413 }
1440114414 }
......@@ -14417,12 +14430,12 @@ fn zirOverflowArithmetic(
1441714430 // Oterhwise if either of the arguments is undefined, both results are undefined.
1441814431 if (maybe_lhs_val) |lhs_val| {
1441914432 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14420 break :result .{ .overflow_bit = try sema.splat(dest_ty, zero), .inst = lhs };
14433 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
1442114434 }
1442214435 }
1442314436 if (maybe_rhs_val) |rhs_val| {
1442414437 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
14425 break :result .{ .overflow_bit = try sema.splat(dest_ty, zero), .inst = lhs };
14438 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
1442614439 }
1442714440 }
1442814441 if (maybe_lhs_val) |lhs_val| {
......@@ -14922,13 +14935,18 @@ fn analyzeArithmetic(
1492214935 .ComptimeInt, .Int => try mod.intValue(scalar_type, 0),
1492314936 else => unreachable,
1492414937 };
14938 const scalar_one = switch (scalar_tag) {
14939 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0),
14940 .ComptimeInt, .Int => try mod.intValue(scalar_type, 1),
14941 else => unreachable,
14942 };
1492514943 if (maybe_lhs_val) |lhs_val| {
1492614944 if (!lhs_val.isUndef(mod)) {
1492714945 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1492814946 const zero_val = try sema.splat(resolved_type, scalar_zero);
1492914947 return sema.addConstant(resolved_type, zero_val);
1493014948 }
14931 if (try sema.compareAll(lhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) {
14949 if (try sema.compareAll(lhs_val, .eq, try sema.splat(resolved_type, scalar_one), resolved_type)) {
1493214950 return casted_rhs;
1493314951 }
1493414952 }
......@@ -14941,7 +14959,7 @@ fn analyzeArithmetic(
1494114959 const zero_val = try sema.splat(resolved_type, scalar_zero);
1494214960 return sema.addConstant(resolved_type, zero_val);
1494314961 }
14944 if (try sema.compareAll(rhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) {
14962 if (try sema.compareAll(rhs_val, .eq, try sema.splat(resolved_type, scalar_one), resolved_type)) {
1494514963 return casted_lhs;
1494614964 }
1494714965 if (maybe_lhs_val) |lhs_val| {
......@@ -19219,10 +19237,9 @@ fn zirReify(
1921919237 try names.ensureUnusedCapacity(sema.arena, len);
1922019238 for (0..len) |i| {
1922119239 const elem_val = try payload_val.elemValue(mod, i);
19222 const struct_val = elem_val.castTag(.aggregate).?.data;
19223 // TODO use reflection instead of magic numbers here
19224 // error_set: type,
19225 const name_val = struct_val[0];
19240 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19241 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
19242
1922619243 const name_str = try name_val.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);
1922719244 const name_ip = try mod.intern_pool.getOrPutString(gpa, name_str);
1922819245 const gop = names.getOrPutAssumeCapacity(name_ip);
......@@ -19303,12 +19320,9 @@ fn zirReify(
1930319320
1930419321 for (0..fields_len) |field_i| {
1930519322 const elem_val = try fields_val.elemValue(mod, field_i);
19306 const field_struct_val: []const Value = elem_val.castTag(.aggregate).?.data;
19307 // TODO use reflection instead of magic numbers here
19308 // name: []const u8
19309 const name_val = field_struct_val[0];
19310 // value: comptime_int
19311 const value_val = field_struct_val[1];
19323 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19324 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
19325 const value_val = try elem_val.fieldValue(mod, elem_fields.getIndex("value").?);
1931219326
1931319327 const field_name = try name_val.toAllocatedBytes(
1931419328 Type.slice_const_u8,
......@@ -19485,14 +19499,10 @@ fn zirReify(
1948519499
1948619500 for (0..fields_len) |i| {
1948719501 const elem_val = try fields_val.elemValue(mod, i);
19488 const field_struct_val = elem_val.castTag(.aggregate).?.data;
19489 // TODO use reflection instead of magic numbers here
19490 // name: []const u8
19491 const name_val = field_struct_val[0];
19492 // type: type,
19493 const type_val = field_struct_val[1];
19494 // alignment: comptime_int,
19495 const alignment_val = field_struct_val[2];
19502 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19503 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
19504 const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);
19505 const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex("alignment").?);
1949619506
1949719507 const field_name = try name_val.toAllocatedBytes(
1949819508 Type.slice_const_u8,
......@@ -19635,25 +19645,21 @@ fn zirReify(
1963519645
1963619646 var noalias_bits: u32 = 0;
1963719647 for (param_types, 0..) |*param_type, i| {
19638 const arg = try params_val.elemValue(mod, i);
19639 const arg_val = arg.castTag(.aggregate).?.data;
19640 // TODO use reflection instead of magic numbers here
19641 // is_generic: bool,
19642 const arg_is_generic = arg_val[0].toBool();
19643 // is_noalias: bool,
19644 const arg_is_noalias = arg_val[1].toBool();
19645 // type: ?type,
19646 const param_type_opt_val = arg_val[2];
19648 const elem_val = try params_val.elemValue(mod, i);
19649 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19650 const param_is_generic_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_generic").?);
19651 const param_is_noalias_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_noalias").?);
19652 const opt_param_type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);
1964719653
19648 if (arg_is_generic) {
19654 if (param_is_generic_val.toBool()) {
1964919655 return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{});
1965019656 }
1965119657
19652 const param_type_val = param_type_opt_val.optionalValue(mod) orelse
19658 const param_type_val = opt_param_type_val.optionalValue(mod) orelse
1965319659 return sema.fail(block, src, "Type.Fn.Param.arg_type must be non-null for @Type", .{});
1965419660 param_type.* = param_type_val.toIntern();
1965519661
19656 if (arg_is_noalias) {
19662 if (param_is_noalias_val.toBool()) {
1965719663 if (!param_type.toType().isPtrAtRuntime(mod)) {
1965819664 return sema.fail(block, src, "non-pointer parameter declared noalias", .{});
1965919665 }
......@@ -19748,19 +19754,13 @@ fn reifyStruct(
1974819754 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
1974919755 var i: usize = 0;
1975019756 while (i < fields_len) : (i += 1) {
19751 const elem_val = try fields_val.elemValue(sema.mod, i);
19752 const field_struct_val = elem_val.castTag(.aggregate).?.data;
19753 // TODO use reflection instead of magic numbers here
19754 // name: []const u8
19755 const name_val = field_struct_val[0];
19756 // type: type,
19757 const type_val = field_struct_val[1];
19758 // default_value: ?*const anyopaque,
19759 const default_value_val = field_struct_val[2];
19760 // is_comptime: bool,
19761 const is_comptime_val = field_struct_val[3];
19762 // alignment: comptime_int,
19763 const alignment_val = field_struct_val[4];
19757 const elem_val = try fields_val.elemValue(mod, i);
19758 const elem_fields = mod.intern_pool.typeOf(elem_val.toIntern()).toType().structFields(mod);
19759 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
19760 const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);
19761 const default_value_val = try elem_val.fieldValue(mod, elem_fields.getIndex("default_value").?);
19762 const is_comptime_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_comptime").?);
19763 const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex("alignment").?);
1976419764
1976519765 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
1976619766 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
......@@ -19806,18 +19806,16 @@ fn reifyStruct(
1980619806 return sema.fail(block, src, "duplicate struct field {s}", .{field_name});
1980719807 }
1980819808
19809 const default_val = if (default_value_val.optionalValue(mod)) |opt_val| blk: {
19810 const payload_val = if (opt_val.pointerDecl(mod)) |opt_decl|
19811 mod.declPtr(opt_decl).val
19812 else
19813 opt_val;
19814 break :blk try payload_val.copy(new_decl_arena_allocator);
19815 } else Value.@"unreachable";
19809 const field_ty = type_val.toType();
19810 const default_val = if (default_value_val.optionalValue(mod)) |opt_val|
19811 try sema.pointerDeref(block, src, opt_val, try mod.singleConstPtrType(field_ty)) orelse
19812 return sema.failWithNeededComptime(block, src, "struct field default value must be comptime-known")
19813 else
19814 Value.@"unreachable";
1981619815 if (is_comptime_val.toBool() and default_val.toIntern() == .unreachable_value) {
1981719816 return sema.fail(block, src, "comptime field without default initialization value", .{});
1981819817 }
1981919818
19820 const field_ty = type_val.toType();
1982119819 gop.value_ptr.* = .{
1982219820 .ty = field_ty,
1982319821 .abi_align = abi_align,
......@@ -20386,17 +20384,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2038620384 if (!dest_ty.ptrAllowsZero(mod) and operand_val.isNull(mod)) {
2038720385 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(mod)});
2038820386 }
20389 return sema.addConstant(aligned_dest_ty, try mod.getCoerced(switch (mod.intern_pool.indexToKey(operand_val.toIntern())) {
20390 .undef, .ptr => operand_val,
20391 .opt => |opt| switch (opt.val) {
20392 .none => if (dest_ty.ptrAllowsZero(mod))
20393 Value.zero_usize
20394 else
20395 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(mod)}),
20396 else => opt.val.toValue(),
20397 },
20398 else => unreachable,
20399 }, aligned_dest_ty));
20387 return sema.addConstant(aligned_dest_ty, try mod.getCoerced(operand_val, aligned_dest_ty));
2040020388 }
2040120389
2040220390 try sema.requireRuntimeBlock(block, src, null);
......@@ -20569,7 +20557,7 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2056920557 return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align });
2057020558 }
2057120559 }
20572 return sema.addConstant(dest_ty, val);
20560 return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));
2057320561 }
2057420562
2057520563 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);
......@@ -20700,7 +20688,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2070020688 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
2070120689 for (elems, 0..) |*elem, i| {
2070220690 const elem_val = try val.elemValue(mod, i);
20703 elem.* = try (try elem_val.byteSwap(operand_ty, mod, sema.arena)).intern(scalar_ty, mod);
20691 elem.* = try (try elem_val.byteSwap(scalar_ty, mod, sema.arena)).intern(scalar_ty, mod);
2070420692 }
2070520693 return sema.addConstant(operand_ty, (try mod.intern(.{ .aggregate = .{
2070620694 .ty = operand_ty.toIntern(),
......@@ -25128,12 +25116,18 @@ fn tupleFieldValByIndex(
2512825116 }
2512925117
2513025118 if (try sema.resolveMaybeUndefVal(tuple_byval)) |tuple_val| {
25131 if (tuple_val.isUndef(mod)) return sema.addConstUndef(field_ty);
2513225119 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {
2513325120 return sema.addConstant(field_ty, opv);
2513425121 }
25135 const field_values = tuple_val.castTag(.aggregate).?.data;
25136 return sema.addConstant(field_ty, field_values[field_index]);
25122 return switch (mod.intern_pool.indexToKey(tuple_val.toIntern())) {
25123 .undef => sema.addConstUndef(field_ty),
25124 .aggregate => |aggregate| sema.addConstant(field_ty, switch (aggregate.storage) {
25125 .bytes => |bytes| try mod.intValue(Type.u8, bytes[0]),
25126 .elems => |elems| elems[field_index].toValue(),
25127 .repeated_elem => |elem| elem.toValue(),
25128 }),
25129 else => unreachable,
25130 };
2513725131 }
2513825132
2513925133 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
......@@ -25883,7 +25877,7 @@ fn coerceExtra(
2588325877 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);
2588425878 if (in_memory_result == .ok) {
2588525879 if (maybe_inst_val) |val| {
25886 return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));
25880 return sema.coerceInMemory(block, val, inst_ty, dest_ty, dest_ty_src);
2588725881 }
2588825882 try sema.requireRuntimeBlock(block, inst_src, null);
2588925883 return block.addBitCast(dest_ty, inst);
......@@ -26072,7 +26066,7 @@ fn coerceExtra(
2607226066 // coercion to C pointer
2607326067 .C => switch (inst_ty.zigTypeTag(mod)) {
2607426068 .Null => {
26075 return sema.addConstant(dest_ty, Value.null);
26069 return sema.addConstant(dest_ty, try mod.getCoerced(Value.null, dest_ty));
2607626070 },
2607726071 .ComptimeInt => {
2607826072 const addr = sema.coerceExtra(block, Type.usize, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) {
......@@ -26548,6 +26542,68 @@ fn coerceExtra(
2654826542 return sema.failWithOwnedErrorMsg(msg);
2654926543}
2655026544
26545fn coerceInMemory(
26546 sema: *Sema,
26547 block: *Block,
26548 val: Value,
26549 src_ty: Type,
26550 dst_ty: Type,
26551 dst_ty_src: LazySrcLoc,
26552) CompileError!Air.Inst.Ref {
26553 const mod = sema.mod;
26554 switch (mod.intern_pool.indexToKey(val.toIntern())) {
26555 .aggregate => |aggregate| {
26556 const dst_ty_key = mod.intern_pool.indexToKey(dst_ty.toIntern());
26557 const dest_len = try sema.usizeCast(
26558 block,
26559 dst_ty_src,
26560 mod.intern_pool.aggregateTypeLen(dst_ty.toIntern()),
26561 );
26562 direct: {
26563 const src_ty_child = switch (mod.intern_pool.indexToKey(src_ty.toIntern())) {
26564 inline .array_type, .vector_type => |seq_type| seq_type.child,
26565 .anon_struct_type, .struct_type => break :direct,
26566 else => unreachable,
26567 };
26568 const dst_ty_child = switch (dst_ty_key) {
26569 inline .array_type, .vector_type => |seq_type| seq_type.child,
26570 .anon_struct_type, .struct_type => break :direct,
26571 else => unreachable,
26572 };
26573 if (src_ty_child != dst_ty_child) break :direct;
26574 return try sema.addConstant(dst_ty, (try mod.intern(.{ .aggregate = .{
26575 .ty = dst_ty.toIntern(),
26576 .storage = switch (aggregate.storage) {
26577 .bytes => |bytes| .{ .bytes = bytes[0..dest_len] },
26578 .elems => |elems| .{ .elems = elems[0..dest_len] },
26579 .repeated_elem => |elem| .{ .repeated_elem = elem },
26580 },
26581 } })).toValue());
26582 }
26583 const dest_elems = try sema.arena.alloc(InternPool.Index, dest_len);
26584 for (dest_elems, 0..) |*dest_elem, i| {
26585 const elem_ty = switch (dst_ty_key) {
26586 inline .array_type, .vector_type => |seq_type| seq_type.child,
26587 .anon_struct_type => |anon_struct_type| anon_struct_type.types[i],
26588 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?
26589 .fields.values()[i].ty.toIntern(),
26590 else => unreachable,
26591 };
26592 dest_elem.* = try mod.intern_pool.getCoerced(mod.gpa, switch (aggregate.storage) {
26593 .bytes => |bytes| (try mod.intValue(Type.u8, bytes[i])).toIntern(),
26594 .elems => |elems| elems[i],
26595 .repeated_elem => |elem| elem,
26596 }, elem_ty);
26597 }
26598 return sema.addConstant(dst_ty, (try mod.intern(.{ .aggregate = .{
26599 .ty = dst_ty.toIntern(),
26600 .storage = .{ .elems = dest_elems },
26601 } })).toValue());
26602 },
26603 else => return sema.addConstant(dst_ty, try mod.getCoerced(val, dst_ty)),
26604 }
26605}
26606
2655126607const InMemoryCoercionResult = union(enum) {
2655226608 ok,
2655326609 no_match: Pair,
......@@ -28619,7 +28675,11 @@ fn coerceArrayPtrToSlice(
2861928675 const array_ty = ptr_array_ty.childType(mod);
2862028676 const slice_val = try mod.intern(.{ .ptr = .{
2862128677 .ty = dest_ty.toIntern(),
28622 .addr = mod.intern_pool.indexToKey(val.toIntern()).ptr.addr,
28678 .addr = switch (mod.intern_pool.indexToKey(val.toIntern())) {
28679 .undef => .{ .int = try mod.intern(.{ .undef = .usize_type }) },
28680 .ptr => |ptr| ptr.addr,
28681 else => unreachable,
28682 },
2862328683 .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(),
2862428684 } });
2862528685 return sema.addConstant(dest_ty, slice_val.toValue());
......@@ -28962,7 +29022,7 @@ fn coerceArrayLike(
2896229022 if (in_memory_result == .ok) {
2896329023 if (try sema.resolveMaybeUndefVal(inst)) |inst_val| {
2896429024 // These types share the same comptime value representation.
28965 return sema.addConstant(dest_ty, try mod.getCoerced(inst_val, dest_ty));
29025 return sema.coerceInMemory(block, inst_val, inst_ty, dest_ty, dest_ty_src);
2896629026 }
2896729027 try sema.requireRuntimeBlock(block, inst_src, null);
2896829028 return block.addBitCast(dest_ty, inst);
......@@ -33599,9 +33659,8 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
3359933659 const mod = sema.mod;
3360033660 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
3360133661 .ptr_type => |ptr_type| switch (ptr_type.size) {
33662 .One, .Many, .C => ty,
3360233663 .Slice => null,
33603 .C => ptr_type.elem_type.toType(),
33604 .One, .Many => ty,
3360533664 },
3360633665 .opt_type => |opt_child| switch (mod.intern_pool.indexToKey(opt_child)) {
3360733666 .ptr_type => |ptr_type| switch (ptr_type.size) {
src/codegen/llvm.zig+17-8
......@@ -3396,7 +3396,7 @@ pub const DeclGen = struct {
33963396 const llvm_ptr_val = switch (ptr.addr) {
33973397 .decl => |decl| try dg.lowerDeclRefValue(ptr_tv, decl),
33983398 .mut_decl => |mut_decl| try dg.lowerDeclRefValue(ptr_tv, mut_decl.decl),
3399 .int => |int| dg.lowerIntAsPtr(mod.intern_pool.indexToKey(int).int),
3399 .int => |int| try dg.lowerIntAsPtr(mod.intern_pool.indexToKey(int)),
34003400 .eu_payload,
34013401 .opt_payload,
34023402 .elem,
......@@ -3796,11 +3796,20 @@ pub const DeclGen = struct {
37963796 }
37973797 }
37983798
3799 fn lowerIntAsPtr(dg: *DeclGen, int: InternPool.Key.Int) *llvm.Value {
3800 var bigint_space: Value.BigIntSpace = undefined;
3801 const bigint = int.storage.toBigInt(&bigint_space);
3802 const llvm_int = lowerBigInt(dg, Type.usize, bigint);
3803 return llvm_int.constIntToPtr(dg.context.pointerType(0));
3799 fn lowerIntAsPtr(dg: *DeclGen, int_key: InternPool.Key) Error!*llvm.Value {
3800 switch (int_key) {
3801 .undef => {
3802 const llvm_usize = try dg.lowerType(Type.usize);
3803 return llvm_usize.getUndef();
3804 },
3805 .int => |int| {
3806 var bigint_space: Value.BigIntSpace = undefined;
3807 const bigint = int.storage.toBigInt(&bigint_space);
3808 const llvm_int = lowerBigInt(dg, Type.usize, bigint);
3809 return llvm_int.constIntToPtr(dg.context.pointerType(0));
3810 },
3811 else => unreachable,
3812 }
38043813 }
38053814
38063815 fn lowerBigInt(dg: *DeclGen, ty: Type, bigint: std.math.big.int.Const) *llvm.Value {
......@@ -3848,11 +3857,11 @@ pub const DeclGen = struct {
38483857 const mod = dg.module;
38493858 const target = mod.getTarget();
38503859 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {
3851 .int => |int| dg.lowerIntAsPtr(int),
3860 .int => |int| dg.lowerIntAsPtr(.{ .int = int }),
38523861 .ptr => |ptr| switch (ptr.addr) {
38533862 .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),
38543863 .mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),
3855 .int => |int| dg.lowerIntAsPtr(mod.intern_pool.indexToKey(int).int),
3864 .int => |int| dg.lowerIntAsPtr(mod.intern_pool.indexToKey(int)),
38563865 .eu_payload => |eu_ptr| {
38573866 const parent_llvm_ptr = try dg.lowerParentPtr(eu_ptr.toValue(), true);
38583867
src/type.zig+2-2
......@@ -2788,7 +2788,7 @@ pub const Type = struct {
27882788
27892789 // Works for vectors and vectors of integers.
27902790 pub fn minInt(ty: Type, mod: *Module, dest_ty: Type) !Value {
2791 const scalar = try minIntScalar(ty.scalarType(mod), mod, dest_ty);
2791 const scalar = try minIntScalar(ty.scalarType(mod), mod, dest_ty.scalarType(mod));
27922792 return if (ty.zigTypeTag(mod) == .Vector) (try mod.intern(.{ .aggregate = .{
27932793 .ty = dest_ty.toIntern(),
27942794 .storage = .{ .repeated_elem = scalar.toIntern() },
......@@ -2817,7 +2817,7 @@ pub const Type = struct {
28172817 // Works for vectors and vectors of integers.
28182818 /// The returned Value will have type dest_ty.
28192819 pub fn maxInt(ty: Type, mod: *Module, dest_ty: Type) !Value {
2820 const scalar = try maxIntScalar(ty.scalarType(mod), mod, dest_ty);
2820 const scalar = try maxIntScalar(ty.scalarType(mod), mod, dest_ty.scalarType(mod));
28212821 return if (ty.zigTypeTag(mod) == .Vector) (try mod.intern(.{ .aggregate = .{
28222822 .ty = dest_ty.toIntern(),
28232823 .storage = .{ .repeated_elem = scalar.toIntern() },
src/value.zig+6-6
......@@ -2340,16 +2340,16 @@ pub const Value = struct {
23402340 const lhs_elem = try lhs.elemValue(mod, i);
23412341 const rhs_elem = try rhs.elemValue(mod, i);
23422342 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod);
2343 of.* = try of_math_result.overflow_bit.intern(Type.bool, mod);
2343 of.* = try of_math_result.overflow_bit.intern(Type.u1, mod);
23442344 scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod);
23452345 }
23462346 return OverflowArithmeticResult{
23472347 .overflow_bit = (try mod.intern(.{ .aggregate = .{
2348 .ty = ty.toIntern(),
2348 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
23492349 .storage = .{ .elems = overflowed_data },
23502350 } })).toValue(),
23512351 .wrapped_result = (try mod.intern(.{ .aggregate = .{
2352 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
2352 .ty = ty.toIntern(),
23532353 .storage = .{ .elems = result_data },
23542354 } })).toValue(),
23552355 };
......@@ -3090,16 +3090,16 @@ pub const Value = struct {
30903090 const lhs_elem = try lhs.elemValue(mod, i);
30913091 const rhs_elem = try rhs.elemValue(mod, i);
30923092 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod);
3093 of.* = try of_math_result.overflow_bit.intern(Type.bool, mod);
3093 of.* = try of_math_result.overflow_bit.intern(Type.u1, mod);
30943094 scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod);
30953095 }
30963096 return OverflowArithmeticResult{
30973097 .overflow_bit = (try mod.intern(.{ .aggregate = .{
3098 .ty = ty.toIntern(),
3098 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
30993099 .storage = .{ .elems = overflowed_data },
31003100 } })).toValue(),
31013101 .wrapped_result = (try mod.intern(.{ .aggregate = .{
3102 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
3102 .ty = ty.toIntern(),
31033103 .storage = .{ .elems = result_data },
31043104 } })).toValue(),
31053105 };
test/behavior/bugs/6456.zig+1-1
......@@ -24,7 +24,7 @@ test "issue 6456" {
2424 .alignment = 0,
2525 .name = name,
2626 .type = usize,
27 .default_value = &@as(?usize, null),
27 .default_value = null,
2828 .is_comptime = false,
2929 }};
3030 }