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 {...@@ -4250,6 +4250,8 @@ pub fn sliceLen(ip: InternPool, i: Index) Index {
4250/// * int <=> enum4250/// * int <=> enum
4251/// * enum_literal => enum4251/// * enum_literal => enum
4252/// * ptr <=> ptr4252/// * ptr <=> ptr
4253/// * opt ptr <=> ptr
4254/// * opt ptr <=> opt ptr
4253/// * int => ptr4255/// * int => ptr
4254/// * null_value => opt4256/// * null_value => opt
4255/// * payload => opt4257/// * payload => opt
...@@ -4258,9 +4260,6 @@ pub fn sliceLen(ip: InternPool, i: Index) Index {...@@ -4258,9 +4260,6 @@ pub fn sliceLen(ip: InternPool, i: Index) Index {
4258/// * error set => error union4260/// * error set => error union
4259/// * payload => error union4261/// * payload => error union
4260/// * fn <=> fn4262/// * fn <=> fn
4261/// * array <=> array
4262/// * array <=> vector
4263/// * vector <=> vector
4264pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {4263pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {
4265 const old_ty = ip.typeOf(val);4264 const old_ty = ip.typeOf(val);
4266 if (old_ty == new_ty) return val;4265 if (old_ty == new_ty) return val;
...@@ -4270,6 +4269,15 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -4270,6 +4269,15 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
4270 return ip.get(gpa, .{ .opt = .{4269 return ip.get(gpa, .{ .opt = .{
4271 .ty = new_ty,4270 .ty = new_ty,
4272 .val = .none,4271 .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 },
4273 } }),4281 } }),
4274 else => switch (ip.indexToKey(val)) {4282 else => switch (ip.indexToKey(val)) {
4275 .undef => return ip.get(gpa, .{ .undef = new_ty }),4283 .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...@@ -4320,6 +4328,18 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
4320 .addr = ptr.addr,4328 .addr = ptr.addr,
4321 .len = ptr.len,4329 .len = ptr.len,
4322 } }),4330 } }),
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 },
4323 .err => |err| if (ip.isErrorSetType(new_ty))4343 .err => |err| if (ip.isErrorSetType(new_ty))
4324 return ip.get(gpa, .{ .err = .{4344 return ip.get(gpa, .{ .err = .{
4325 .ty = new_ty,4345 .ty = new_ty,
...@@ -4335,14 +4355,6 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -4335,14 +4355,6 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
4335 .ty = new_ty,4355 .ty = new_ty,
4336 .val = error_union.val,4356 .val = error_union.val,
4337 } }),4357 } }),
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 } }),
4346 else => {},4358 else => {},
4347 },4359 },
4348 }4360 }
...@@ -4364,8 +4376,10 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -4364,8 +4376,10 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
4364 else => {},4376 else => {},
4365 }4377 }
4366 if (std.debug.runtime_safety) {4378 if (std.debug.runtime_safety) {
4367 std.debug.panic("val={any} new_ty={any}\n", .{4379 std.debug.panic("InternPool.getCoerced of {s} not implemented from {s} to {s}", .{
4368 ip.items.get(@enumToInt(val)), ip.items.get(@enumToInt(new_ty)),4380 @tagName(ip.indexToKey(val)),
4381 @tagName(ip.indexToKey(old_ty)),
4382 @tagName(ip.indexToKey(new_ty)),
4369 });4383 });
4370 }4384 }
4371 unreachable;4385 unreachable;
...@@ -4507,6 +4521,13 @@ pub fn isErrorUnionType(ip: InternPool, ty: Index) bool {...@@ -4507,6 +4521,13 @@ pub fn isErrorUnionType(ip: InternPool, ty: Index) bool {
4507 return ip.indexToKey(ty) == .error_union_type;4521 return ip.indexToKey(ty) == .error_union_type;
4508}4522}
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
4510/// The is only legal because the initializer is not part of the hash.4531/// The is only legal because the initializer is not part of the hash.
4511pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {4532pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {
4512 assert(ip.items.items(.tag)[@enumToInt(index)] == .variable);4533 assert(ip.items.items(.tag)[@enumToInt(index)] == .variable);
src/Sema.zig+148-89
...@@ -6381,8 +6381,7 @@ fn zirCall(...@@ -6381,8 +6381,7 @@ fn zirCall(
6381 var input_is_error = false;6381 var input_is_error = false;
6382 const block_index = @intCast(Air.Inst.Index, block.instructions.items.len);6382 const block_index = @intCast(Air.Inst.Index, block.instructions.items.len);
63836383
6384 const func_ty_info = mod.typeToFunc(func_ty).?;6384 const fn_params_len = mod.typeToFunc(func_ty).?.param_types.len;
6385 const fn_params_len = func_ty_info.param_types.len;
6386 const parent_comptime = block.is_comptime;6385 const parent_comptime = block.is_comptime;
6387 // `extra_index` and `arg_index` are separate since the bound function is passed as the first argument.6386 // `extra_index` and `arg_index` are separate since the bound function is passed as the first argument.
6388 var extra_index: usize = 0;6387 var extra_index: usize = 0;
...@@ -6391,6 +6390,7 @@ fn zirCall(...@@ -6391,6 +6390,7 @@ fn zirCall(
6391 extra_index += 1;6390 extra_index += 1;
6392 arg_index += 1;6391 arg_index += 1;
6393 }) {6392 }) {
6393 const func_ty_info = mod.typeToFunc(func_ty).?;
6394 const arg_end = sema.code.extra[extra.end + extra_index];6394 const arg_end = sema.code.extra[extra.end + extra_index];
6395 defer arg_start = arg_end;6395 defer arg_start = arg_end;
63966396
...@@ -6876,7 +6876,11 @@ fn analyzeCall(...@@ -6876,7 +6876,11 @@ fn analyzeCall(
6876 .args_count = @intCast(u32, func_ty_info.param_types.len),6876 .args_count = @intCast(u32, func_ty_info.param_types.len),
6877 };6877 };
6878 var delete_memoized_call_key = false;6878 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 };
6880 if (is_comptime_call) {6884 if (is_comptime_call) {
6881 try mod.memoized_call_args.ensureUnusedCapacity(gpa, memoized_call_key.args_count);6885 try mod.memoized_call_args.ensureUnusedCapacity(gpa, memoized_call_key.args_count);
6882 delete_memoized_call_key = true;6886 delete_memoized_call_key = true;
...@@ -6990,14 +6994,22 @@ fn analyzeCall(...@@ -6990,14 +6994,22 @@ fn analyzeCall(
6990 .{ .args = &mod.memoized_call_args },6994 .{ .args = &mod.memoized_call_args },
6991 );6995 );
6992 if (gop.found_existing) {6996 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
6993 // We need to use the original memoized error set instead of fn_ret_ty.7001 // We need to use the original memoized error set instead of fn_ret_ty.
6994 const result = gop.value_ptr.*;7002 const result = gop.value_ptr.*;
6995 assert(result != .none); // recursive memoization?7003 assert(result != .none); // recursive memoization?
7004
6996 break :res2 try sema.addConstant(mod.intern_pool.typeOf(result).toType(), result.toValue());7005 break :res2 try sema.addConstant(mod.intern_pool.typeOf(result).toType(), result.toValue());
6997 }7006 }
6998 gop.value_ptr.* = .none;7007 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);
7000 }7011 }
7012 delete_memoized_call_key = false;
70017013
7002 const new_func_resolved_ty = try mod.funcType(new_fn_info);7014 const new_func_resolved_ty = try mod.funcType(new_fn_info);
7003 if (!is_comptime_call and !block.is_typeof) {7015 if (!is_comptime_call and !block.is_typeof) {
...@@ -14324,13 +14336,14 @@ fn zirOverflowArithmetic(...@@ -14324,13 +14336,14 @@ fn zirOverflowArithmetic(
14324 const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);14336 const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);
1432514337
14326 const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);14338 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
14328 var result: struct {14341 var result: struct {
14329 inst: Air.Inst.Ref = .none,14342 inst: Air.Inst.Ref = .none,
14330 wrapped: Value = Value.@"unreachable",14343 wrapped: Value = Value.@"unreachable",
14331 overflow_bit: Value,14344 overflow_bit: Value,
14332 } = result: {14345 } = result: {
14333 const zero = try mod.intValue(dest_ty.scalarType(mod), 0);14346 const zero_bit = try mod.intValue(Type.u1, 0);
14334 switch (zir_tag) {14347 switch (zir_tag) {
14335 .add_with_overflow => {14348 .add_with_overflow => {
14336 // If either of the arguments is zero, `false` is returned and the other is stored14349 // If either of the arguments is zero, `false` is returned and the other is stored
...@@ -14338,12 +14351,12 @@ fn zirOverflowArithmetic(...@@ -14338,12 +14351,12 @@ fn zirOverflowArithmetic(
14338 // Otherwise, if either of the argument is undefined, undefined is returned.14351 // Otherwise, if either of the argument is undefined, undefined is returned.
14339 if (maybe_lhs_val) |lhs_val| {14352 if (maybe_lhs_val) |lhs_val| {
14340 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {14353 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 };
14342 }14355 }
14343 }14356 }
14344 if (maybe_rhs_val) |rhs_val| {14357 if (maybe_rhs_val) |rhs_val| {
14345 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {14358 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 };
14347 }14360 }
14348 }14361 }
14349 if (maybe_lhs_val) |lhs_val| {14362 if (maybe_lhs_val) |lhs_val| {
...@@ -14364,7 +14377,7 @@ fn zirOverflowArithmetic(...@@ -14364,7 +14377,7 @@ fn zirOverflowArithmetic(
14364 if (rhs_val.isUndef(mod)) {14377 if (rhs_val.isUndef(mod)) {
14365 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };14378 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
14366 } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14379 } 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 };
14368 } else if (maybe_lhs_val) |lhs_val| {14381 } else if (maybe_lhs_val) |lhs_val| {
14369 if (lhs_val.isUndef(mod)) {14382 if (lhs_val.isUndef(mod)) {
14370 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };14383 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
...@@ -14383,9 +14396,9 @@ fn zirOverflowArithmetic(...@@ -14383,9 +14396,9 @@ fn zirOverflowArithmetic(
14383 if (maybe_lhs_val) |lhs_val| {14396 if (maybe_lhs_val) |lhs_val| {
14384 if (!lhs_val.isUndef(mod)) {14397 if (!lhs_val.isUndef(mod)) {
14385 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14398 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 };
14387 } else if (try sema.compareAll(lhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {14400 } 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 };
14389 }14402 }
14390 }14403 }
14391 }14404 }
...@@ -14393,9 +14406,9 @@ fn zirOverflowArithmetic(...@@ -14393,9 +14406,9 @@ fn zirOverflowArithmetic(
14393 if (maybe_rhs_val) |rhs_val| {14406 if (maybe_rhs_val) |rhs_val| {
14394 if (!rhs_val.isUndef(mod)) {14407 if (!rhs_val.isUndef(mod)) {
14395 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14408 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 };
14397 } else if (try sema.compareAll(rhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {14410 } 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 };
14399 }14412 }
14400 }14413 }
14401 }14414 }
...@@ -14417,12 +14430,12 @@ fn zirOverflowArithmetic(...@@ -14417,12 +14430,12 @@ fn zirOverflowArithmetic(
14417 // Oterhwise if either of the arguments is undefined, both results are undefined.14430 // Oterhwise if either of the arguments is undefined, both results are undefined.
14418 if (maybe_lhs_val) |lhs_val| {14431 if (maybe_lhs_val) |lhs_val| {
14419 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {14432 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 };
14421 }14434 }
14422 }14435 }
14423 if (maybe_rhs_val) |rhs_val| {14436 if (maybe_rhs_val) |rhs_val| {
14424 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {14437 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 };
14426 }14439 }
14427 }14440 }
14428 if (maybe_lhs_val) |lhs_val| {14441 if (maybe_lhs_val) |lhs_val| {
...@@ -14922,13 +14935,18 @@ fn analyzeArithmetic(...@@ -14922,13 +14935,18 @@ fn analyzeArithmetic(
14922 .ComptimeInt, .Int => try mod.intValue(scalar_type, 0),14935 .ComptimeInt, .Int => try mod.intValue(scalar_type, 0),
14923 else => unreachable,14936 else => unreachable,
14924 };14937 };
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 };
14925 if (maybe_lhs_val) |lhs_val| {14943 if (maybe_lhs_val) |lhs_val| {
14926 if (!lhs_val.isUndef(mod)) {14944 if (!lhs_val.isUndef(mod)) {
14927 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14945 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
14928 const zero_val = try sema.splat(resolved_type, scalar_zero);14946 const zero_val = try sema.splat(resolved_type, scalar_zero);
14929 return sema.addConstant(resolved_type, zero_val);14947 return sema.addConstant(resolved_type, zero_val);
14930 }14948 }
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)) {
14932 return casted_rhs;14950 return casted_rhs;
14933 }14951 }
14934 }14952 }
...@@ -14941,7 +14959,7 @@ fn analyzeArithmetic(...@@ -14941,7 +14959,7 @@ fn analyzeArithmetic(
14941 const zero_val = try sema.splat(resolved_type, scalar_zero);14959 const zero_val = try sema.splat(resolved_type, scalar_zero);
14942 return sema.addConstant(resolved_type, zero_val);14960 return sema.addConstant(resolved_type, zero_val);
14943 }14961 }
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)) {
14945 return casted_lhs;14963 return casted_lhs;
14946 }14964 }
14947 if (maybe_lhs_val) |lhs_val| {14965 if (maybe_lhs_val) |lhs_val| {
...@@ -19219,10 +19237,9 @@ fn zirReify(...@@ -19219,10 +19237,9 @@ fn zirReify(
19219 try names.ensureUnusedCapacity(sema.arena, len);19237 try names.ensureUnusedCapacity(sema.arena, len);
19220 for (0..len) |i| {19238 for (0..len) |i| {
19221 const elem_val = try payload_val.elemValue(mod, i);19239 const elem_val = try payload_val.elemValue(mod, i);
19222 const struct_val = elem_val.castTag(.aggregate).?.data;19240 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19223 // TODO use reflection instead of magic numbers here19241 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
19224 // error_set: type,19242
19225 const name_val = struct_val[0];
19226 const name_str = try name_val.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);19243 const name_str = try name_val.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);
19227 const name_ip = try mod.intern_pool.getOrPutString(gpa, name_str);19244 const name_ip = try mod.intern_pool.getOrPutString(gpa, name_str);
19228 const gop = names.getOrPutAssumeCapacity(name_ip);19245 const gop = names.getOrPutAssumeCapacity(name_ip);
...@@ -19303,12 +19320,9 @@ fn zirReify(...@@ -19303,12 +19320,9 @@ fn zirReify(
1930319320
19304 for (0..fields_len) |field_i| {19321 for (0..fields_len) |field_i| {
19305 const elem_val = try fields_val.elemValue(mod, field_i);19322 const elem_val = try fields_val.elemValue(mod, field_i);
19306 const field_struct_val: []const Value = elem_val.castTag(.aggregate).?.data;19323 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19307 // TODO use reflection instead of magic numbers here19324 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
19308 // name: []const u819325 const value_val = try elem_val.fieldValue(mod, elem_fields.getIndex("value").?);
19309 const name_val = field_struct_val[0];
19310 // value: comptime_int
19311 const value_val = field_struct_val[1];
1931219326
19313 const field_name = try name_val.toAllocatedBytes(19327 const field_name = try name_val.toAllocatedBytes(
19314 Type.slice_const_u8,19328 Type.slice_const_u8,
...@@ -19485,14 +19499,10 @@ fn zirReify(...@@ -19485,14 +19499,10 @@ fn zirReify(
1948519499
19486 for (0..fields_len) |i| {19500 for (0..fields_len) |i| {
19487 const elem_val = try fields_val.elemValue(mod, i);19501 const elem_val = try fields_val.elemValue(mod, i);
19488 const field_struct_val = elem_val.castTag(.aggregate).?.data;19502 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19489 // TODO use reflection instead of magic numbers here19503 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
19490 // name: []const u819504 const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);
19491 const name_val = field_struct_val[0];19505 const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex("alignment").?);
19492 // type: type,
19493 const type_val = field_struct_val[1];
19494 // alignment: comptime_int,
19495 const alignment_val = field_struct_val[2];
1949619506
19497 const field_name = try name_val.toAllocatedBytes(19507 const field_name = try name_val.toAllocatedBytes(
19498 Type.slice_const_u8,19508 Type.slice_const_u8,
...@@ -19635,25 +19645,21 @@ fn zirReify(...@@ -19635,25 +19645,21 @@ fn zirReify(
1963519645
19636 var noalias_bits: u32 = 0;19646 var noalias_bits: u32 = 0;
19637 for (param_types, 0..) |*param_type, i| {19647 for (param_types, 0..) |*param_type, i| {
19638 const arg = try params_val.elemValue(mod, i);19648 const elem_val = try params_val.elemValue(mod, i);
19639 const arg_val = arg.castTag(.aggregate).?.data;19649 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19640 // TODO use reflection instead of magic numbers here19650 const param_is_generic_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_generic").?);
19641 // is_generic: bool,19651 const param_is_noalias_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_noalias").?);
19642 const arg_is_generic = arg_val[0].toBool();19652 const opt_param_type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);
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];
1964719653
19648 if (arg_is_generic) {19654 if (param_is_generic_val.toBool()) {
19649 return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{});19655 return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{});
19650 }19656 }
1965119657
19652 const param_type_val = param_type_opt_val.optionalValue(mod) orelse19658 const param_type_val = opt_param_type_val.optionalValue(mod) orelse
19653 return sema.fail(block, src, "Type.Fn.Param.arg_type must be non-null for @Type", .{});19659 return sema.fail(block, src, "Type.Fn.Param.arg_type must be non-null for @Type", .{});
19654 param_type.* = param_type_val.toIntern();19660 param_type.* = param_type_val.toIntern();
1965519661
19656 if (arg_is_noalias) {19662 if (param_is_noalias_val.toBool()) {
19657 if (!param_type.toType().isPtrAtRuntime(mod)) {19663 if (!param_type.toType().isPtrAtRuntime(mod)) {
19658 return sema.fail(block, src, "non-pointer parameter declared noalias", .{});19664 return sema.fail(block, src, "non-pointer parameter declared noalias", .{});
19659 }19665 }
...@@ -19748,19 +19754,13 @@ fn reifyStruct(...@@ -19748,19 +19754,13 @@ fn reifyStruct(
19748 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);19754 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
19749 var i: usize = 0;19755 var i: usize = 0;
19750 while (i < fields_len) : (i += 1) {19756 while (i < fields_len) : (i += 1) {
19751 const elem_val = try fields_val.elemValue(sema.mod, i);19757 const elem_val = try fields_val.elemValue(mod, i);
19752 const field_struct_val = elem_val.castTag(.aggregate).?.data;19758 const elem_fields = mod.intern_pool.typeOf(elem_val.toIntern()).toType().structFields(mod);
19753 // TODO use reflection instead of magic numbers here19759 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
19754 // name: []const u819760 const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);
19755 const name_val = field_struct_val[0];19761 const default_value_val = try elem_val.fieldValue(mod, elem_fields.getIndex("default_value").?);
19756 // type: type,19762 const is_comptime_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_comptime").?);
19757 const type_val = field_struct_val[1];19763 const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex("alignment").?);
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];
1976419764
19765 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {19765 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
19766 return sema.fail(block, src, "alignment must fit in 'u32'", .{});19766 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
...@@ -19806,18 +19806,16 @@ fn reifyStruct(...@@ -19806,18 +19806,16 @@ fn reifyStruct(
19806 return sema.fail(block, src, "duplicate struct field {s}", .{field_name});19806 return sema.fail(block, src, "duplicate struct field {s}", .{field_name});
19807 }19807 }
1980819808
19809 const default_val = if (default_value_val.optionalValue(mod)) |opt_val| blk: {19809 const field_ty = type_val.toType();
19810 const payload_val = if (opt_val.pointerDecl(mod)) |opt_decl|19810 const default_val = if (default_value_val.optionalValue(mod)) |opt_val|
19811 mod.declPtr(opt_decl).val19811 try sema.pointerDeref(block, src, opt_val, try mod.singleConstPtrType(field_ty)) orelse
19812 else19812 return sema.failWithNeededComptime(block, src, "struct field default value must be comptime-known")
19813 opt_val;19813 else
19814 break :blk try payload_val.copy(new_decl_arena_allocator);19814 Value.@"unreachable";
19815 } else Value.@"unreachable";
19816 if (is_comptime_val.toBool() and default_val.toIntern() == .unreachable_value) {19815 if (is_comptime_val.toBool() and default_val.toIntern() == .unreachable_value) {
19817 return sema.fail(block, src, "comptime field without default initialization value", .{});19816 return sema.fail(block, src, "comptime field without default initialization value", .{});
19818 }19817 }
1981919818
19820 const field_ty = type_val.toType();
19821 gop.value_ptr.* = .{19819 gop.value_ptr.* = .{
19822 .ty = field_ty,19820 .ty = field_ty,
19823 .abi_align = abi_align,19821 .abi_align = abi_align,
...@@ -20386,17 +20384,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -20386,17 +20384,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
20386 if (!dest_ty.ptrAllowsZero(mod) and operand_val.isNull(mod)) {20384 if (!dest_ty.ptrAllowsZero(mod) and operand_val.isNull(mod)) {
20387 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(mod)});20385 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(mod)});
20388 }20386 }
20389 return sema.addConstant(aligned_dest_ty, try mod.getCoerced(switch (mod.intern_pool.indexToKey(operand_val.toIntern())) {20387 return sema.addConstant(aligned_dest_ty, try mod.getCoerced(operand_val, aligned_dest_ty));
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));
20400 }20388 }
2040120389
20402 try sema.requireRuntimeBlock(block, src, null);20390 try sema.requireRuntimeBlock(block, src, null);
...@@ -20569,7 +20557,7 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -20569,7 +20557,7 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
20569 return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align });20557 return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align });
20570 }20558 }
20571 }20559 }
20572 return sema.addConstant(dest_ty, val);20560 return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));
20573 }20561 }
2057420562
20575 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);20563 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...@@ -20700,7 +20688,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20700 const elems = try sema.arena.alloc(InternPool.Index, vec_len);20688 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
20701 for (elems, 0..) |*elem, i| {20689 for (elems, 0..) |*elem, i| {
20702 const elem_val = try val.elemValue(mod, i);20690 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);
20704 }20692 }
20705 return sema.addConstant(operand_ty, (try mod.intern(.{ .aggregate = .{20693 return sema.addConstant(operand_ty, (try mod.intern(.{ .aggregate = .{
20706 .ty = operand_ty.toIntern(),20694 .ty = operand_ty.toIntern(),
...@@ -25128,12 +25116,18 @@ fn tupleFieldValByIndex(...@@ -25128,12 +25116,18 @@ fn tupleFieldValByIndex(
25128 }25116 }
2512925117
25130 if (try sema.resolveMaybeUndefVal(tuple_byval)) |tuple_val| {25118 if (try sema.resolveMaybeUndefVal(tuple_byval)) |tuple_val| {
25131 if (tuple_val.isUndef(mod)) return sema.addConstUndef(field_ty);
25132 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {25119 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {
25133 return sema.addConstant(field_ty, opv);25120 return sema.addConstant(field_ty, opv);
25134 }25121 }
25135 const field_values = tuple_val.castTag(.aggregate).?.data;25122 return switch (mod.intern_pool.indexToKey(tuple_val.toIntern())) {
25136 return sema.addConstant(field_ty, field_values[field_index]);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 };
25137 }25131 }
2513825132
25139 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {25133 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
...@@ -25883,7 +25877,7 @@ fn coerceExtra(...@@ -25883,7 +25877,7 @@ fn coerceExtra(
25883 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);25877 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);
25884 if (in_memory_result == .ok) {25878 if (in_memory_result == .ok) {
25885 if (maybe_inst_val) |val| {25879 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);
25887 }25881 }
25888 try sema.requireRuntimeBlock(block, inst_src, null);25882 try sema.requireRuntimeBlock(block, inst_src, null);
25889 return block.addBitCast(dest_ty, inst);25883 return block.addBitCast(dest_ty, inst);
...@@ -26072,7 +26066,7 @@ fn coerceExtra(...@@ -26072,7 +26066,7 @@ fn coerceExtra(
26072 // coercion to C pointer26066 // coercion to C pointer
26073 .C => switch (inst_ty.zigTypeTag(mod)) {26067 .C => switch (inst_ty.zigTypeTag(mod)) {
26074 .Null => {26068 .Null => {
26075 return sema.addConstant(dest_ty, Value.null);26069 return sema.addConstant(dest_ty, try mod.getCoerced(Value.null, dest_ty));
26076 },26070 },
26077 .ComptimeInt => {26071 .ComptimeInt => {
26078 const addr = sema.coerceExtra(block, Type.usize, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) {26072 const addr = sema.coerceExtra(block, Type.usize, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) {
...@@ -26548,6 +26542,68 @@ fn coerceExtra(...@@ -26548,6 +26542,68 @@ fn coerceExtra(
26548 return sema.failWithOwnedErrorMsg(msg);26542 return sema.failWithOwnedErrorMsg(msg);
26549}26543}
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
26551const InMemoryCoercionResult = union(enum) {26607const InMemoryCoercionResult = union(enum) {
26552 ok,26608 ok,
26553 no_match: Pair,26609 no_match: Pair,
...@@ -28619,7 +28675,11 @@ fn coerceArrayPtrToSlice(...@@ -28619,7 +28675,11 @@ fn coerceArrayPtrToSlice(
28619 const array_ty = ptr_array_ty.childType(mod);28675 const array_ty = ptr_array_ty.childType(mod);
28620 const slice_val = try mod.intern(.{ .ptr = .{28676 const slice_val = try mod.intern(.{ .ptr = .{
28621 .ty = dest_ty.toIntern(),28677 .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 },
28623 .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(),28683 .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(),
28624 } });28684 } });
28625 return sema.addConstant(dest_ty, slice_val.toValue());28685 return sema.addConstant(dest_ty, slice_val.toValue());
...@@ -28962,7 +29022,7 @@ fn coerceArrayLike(...@@ -28962,7 +29022,7 @@ fn coerceArrayLike(
28962 if (in_memory_result == .ok) {29022 if (in_memory_result == .ok) {
28963 if (try sema.resolveMaybeUndefVal(inst)) |inst_val| {29023 if (try sema.resolveMaybeUndefVal(inst)) |inst_val| {
28964 // These types share the same comptime value representation.29024 // 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);
28966 }29026 }
28967 try sema.requireRuntimeBlock(block, inst_src, null);29027 try sema.requireRuntimeBlock(block, inst_src, null);
28968 return block.addBitCast(dest_ty, inst);29028 return block.addBitCast(dest_ty, inst);
...@@ -33599,9 +33659,8 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {...@@ -33599,9 +33659,8 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
33599 const mod = sema.mod;33659 const mod = sema.mod;
33600 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {33660 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
33601 .ptr_type => |ptr_type| switch (ptr_type.size) {33661 .ptr_type => |ptr_type| switch (ptr_type.size) {
33662 .One, .Many, .C => ty,
33602 .Slice => null,33663 .Slice => null,
33603 .C => ptr_type.elem_type.toType(),
33604 .One, .Many => ty,
33605 },33664 },
33606 .opt_type => |opt_child| switch (mod.intern_pool.indexToKey(opt_child)) {33665 .opt_type => |opt_child| switch (mod.intern_pool.indexToKey(opt_child)) {
33607 .ptr_type => |ptr_type| switch (ptr_type.size) {33666 .ptr_type => |ptr_type| switch (ptr_type.size) {
src/codegen/llvm.zig+17-8
...@@ -3396,7 +3396,7 @@ pub const DeclGen = struct {...@@ -3396,7 +3396,7 @@ pub const DeclGen = struct {
3396 const llvm_ptr_val = switch (ptr.addr) {3396 const llvm_ptr_val = switch (ptr.addr) {
3397 .decl => |decl| try dg.lowerDeclRefValue(ptr_tv, decl),3397 .decl => |decl| try dg.lowerDeclRefValue(ptr_tv, decl),
3398 .mut_decl => |mut_decl| try dg.lowerDeclRefValue(ptr_tv, mut_decl.decl),3398 .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)),
3400 .eu_payload,3400 .eu_payload,
3401 .opt_payload,3401 .opt_payload,
3402 .elem,3402 .elem,
...@@ -3796,11 +3796,20 @@ pub const DeclGen = struct {...@@ -3796,11 +3796,20 @@ pub const DeclGen = struct {
3796 }3796 }
3797 }3797 }
37983798
3799 fn lowerIntAsPtr(dg: *DeclGen, int: InternPool.Key.Int) *llvm.Value {3799 fn lowerIntAsPtr(dg: *DeclGen, int_key: InternPool.Key) Error!*llvm.Value {
3800 var bigint_space: Value.BigIntSpace = undefined;3800 switch (int_key) {
3801 const bigint = int.storage.toBigInt(&bigint_space);3801 .undef => {
3802 const llvm_int = lowerBigInt(dg, Type.usize, bigint);3802 const llvm_usize = try dg.lowerType(Type.usize);
3803 return llvm_int.constIntToPtr(dg.context.pointerType(0));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 }
3804 }3813 }
38053814
3806 fn lowerBigInt(dg: *DeclGen, ty: Type, bigint: std.math.big.int.Const) *llvm.Value {3815 fn lowerBigInt(dg: *DeclGen, ty: Type, bigint: std.math.big.int.Const) *llvm.Value {
...@@ -3848,11 +3857,11 @@ pub const DeclGen = struct {...@@ -3848,11 +3857,11 @@ pub const DeclGen = struct {
3848 const mod = dg.module;3857 const mod = dg.module;
3849 const target = mod.getTarget();3858 const target = mod.getTarget();
3850 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {3859 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {
3851 .int => |int| dg.lowerIntAsPtr(int),3860 .int => |int| dg.lowerIntAsPtr(.{ .int = int }),
3852 .ptr => |ptr| switch (ptr.addr) {3861 .ptr => |ptr| switch (ptr.addr) {
3853 .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),3862 .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),
3854 .mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),3863 .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)),
3856 .eu_payload => |eu_ptr| {3865 .eu_payload => |eu_ptr| {
3857 const parent_llvm_ptr = try dg.lowerParentPtr(eu_ptr.toValue(), true);3866 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 {...@@ -2788,7 +2788,7 @@ pub const Type = struct {
27882788
2789 // Works for vectors and vectors of integers.2789 // Works for vectors and vectors of integers.
2790 pub fn minInt(ty: Type, mod: *Module, dest_ty: Type) !Value {2790 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));
2792 return if (ty.zigTypeTag(mod) == .Vector) (try mod.intern(.{ .aggregate = .{2792 return if (ty.zigTypeTag(mod) == .Vector) (try mod.intern(.{ .aggregate = .{
2793 .ty = dest_ty.toIntern(),2793 .ty = dest_ty.toIntern(),
2794 .storage = .{ .repeated_elem = scalar.toIntern() },2794 .storage = .{ .repeated_elem = scalar.toIntern() },
...@@ -2817,7 +2817,7 @@ pub const Type = struct {...@@ -2817,7 +2817,7 @@ pub const Type = struct {
2817 // Works for vectors and vectors of integers.2817 // Works for vectors and vectors of integers.
2818 /// The returned Value will have type dest_ty.2818 /// The returned Value will have type dest_ty.
2819 pub fn maxInt(ty: Type, mod: *Module, dest_ty: Type) !Value {2819 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));
2821 return if (ty.zigTypeTag(mod) == .Vector) (try mod.intern(.{ .aggregate = .{2821 return if (ty.zigTypeTag(mod) == .Vector) (try mod.intern(.{ .aggregate = .{
2822 .ty = dest_ty.toIntern(),2822 .ty = dest_ty.toIntern(),
2823 .storage = .{ .repeated_elem = scalar.toIntern() },2823 .storage = .{ .repeated_elem = scalar.toIntern() },
src/value.zig+6-6
...@@ -2340,16 +2340,16 @@ pub const Value = struct {...@@ -2340,16 +2340,16 @@ pub const Value = struct {
2340 const lhs_elem = try lhs.elemValue(mod, i);2340 const lhs_elem = try lhs.elemValue(mod, i);
2341 const rhs_elem = try rhs.elemValue(mod, i);2341 const rhs_elem = try rhs.elemValue(mod, i);
2342 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod);2342 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);
2344 scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod);2344 scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod);
2345 }2345 }
2346 return OverflowArithmeticResult{2346 return OverflowArithmeticResult{
2347 .overflow_bit = (try mod.intern(.{ .aggregate = .{2347 .overflow_bit = (try mod.intern(.{ .aggregate = .{
2348 .ty = ty.toIntern(),2348 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
2349 .storage = .{ .elems = overflowed_data },2349 .storage = .{ .elems = overflowed_data },
2350 } })).toValue(),2350 } })).toValue(),
2351 .wrapped_result = (try mod.intern(.{ .aggregate = .{2351 .wrapped_result = (try mod.intern(.{ .aggregate = .{
2352 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),2352 .ty = ty.toIntern(),
2353 .storage = .{ .elems = result_data },2353 .storage = .{ .elems = result_data },
2354 } })).toValue(),2354 } })).toValue(),
2355 };2355 };
...@@ -3090,16 +3090,16 @@ pub const Value = struct {...@@ -3090,16 +3090,16 @@ pub const Value = struct {
3090 const lhs_elem = try lhs.elemValue(mod, i);3090 const lhs_elem = try lhs.elemValue(mod, i);
3091 const rhs_elem = try rhs.elemValue(mod, i);3091 const rhs_elem = try rhs.elemValue(mod, i);
3092 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod);3092 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);
3094 scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod);3094 scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod);
3095 }3095 }
3096 return OverflowArithmeticResult{3096 return OverflowArithmeticResult{
3097 .overflow_bit = (try mod.intern(.{ .aggregate = .{3097 .overflow_bit = (try mod.intern(.{ .aggregate = .{
3098 .ty = ty.toIntern(),3098 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),
3099 .storage = .{ .elems = overflowed_data },3099 .storage = .{ .elems = overflowed_data },
3100 } })).toValue(),3100 } })).toValue(),
3101 .wrapped_result = (try mod.intern(.{ .aggregate = .{3101 .wrapped_result = (try mod.intern(.{ .aggregate = .{
3102 .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(),3102 .ty = ty.toIntern(),
3103 .storage = .{ .elems = result_data },3103 .storage = .{ .elems = result_data },
3104 } })).toValue(),3104 } })).toValue(),
3105 };3105 };
test/behavior/bugs/6456.zig+1-1
...@@ -24,7 +24,7 @@ test "issue 6456" {...@@ -24,7 +24,7 @@ test "issue 6456" {
24 .alignment = 0,24 .alignment = 0,
25 .name = name,25 .name = name,
26 .type = usize,26 .type = usize,
27 .default_value = &@as(?usize, null),27 .default_value = null,
28 .is_comptime = false,28 .is_comptime = false,
29 }};29 }};
30 }30 }