stage1: fix constness in some corner cases

- for one-possible-value types, ir_analyze_struct_field_ptr()
  no longer hardcodes const/volatile

- when slicing arrays, ir_analyze_instruction_slice()
  no longer consults ConstValSpecialStatic

closes #5474
master
Michael Dusan 2020-06-05 00:48:36 -04:00
parent f839d34baa
commit c0c9d11d8c
No known key found for this signature in database
GPG Key ID: ED4C5BA849FA1B74
3 changed files with 62 additions and 4 deletions

View File

@ -21924,7 +21924,9 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
case OnePossibleValueYes: {
IrInstGen *elem = ir_const_move(ira, source_instr,
get_the_one_possible_value(ira->codegen, field_type));
return ir_get_ref(ira, source_instr, elem, false, false);
return ir_get_ref(ira, source_instr, elem,
struct_ptr->value->type->data.pointer.is_const,
struct_ptr->value->type->data.pointer.is_volatile);
}
case OnePossibleValueNo:
break;
@ -27097,10 +27099,8 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
if (array_type->id == ZigTypeIdArray) {
elem_type = array_type->data.array.child_type;
bool is_comptime_const = ptr_ptr->value->special == ConstValSpecialStatic &&
ptr_ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst;
non_sentinel_slice_ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type,
ptr_ptr_type->data.pointer.is_const || is_comptime_const,
ptr_ptr_type->data.pointer.is_const,
ptr_ptr_type->data.pointer.is_volatile,
PtrLenUnknown,
ptr_ptr_type->data.pointer.explicit_alignment, 0, 0, false);

View File

@ -50,6 +50,7 @@ comptime {
_ = @import("behavior/bugs/4769_b.zig");
_ = @import("behavior/bugs/4769_c.zig");
_ = @import("behavior/bugs/4954.zig");
_ = @import("behavior/bugs/5474.zig");
_ = @import("behavior/bugs/5487.zig");
_ = @import("behavior/bugs/394.zig");
_ = @import("behavior/bugs/421.zig");

View File

@ -0,0 +1,57 @@
const std = @import("std");
// baseline (control) struct with array of scalar
const Box0 = struct {
items: [4]Item,
const Item = struct {
num: u32,
};
};
// struct with array of empty struct
const Box1 = struct {
items: [4]Item,
const Item = struct {};
};
// struct with array of zero-size struct
const Box2 = struct {
items: [4]Item,
const Item = struct {
nothing: void,
};
};
fn doTest() void {
// var
{
var box0: Box0 = .{ .items = undefined };
std.testing.expect(@typeInfo(@TypeOf(box0.items[0..])).Pointer.is_const == false);
var box1: Box1 = .{ .items = undefined };
std.testing.expect(@typeInfo(@TypeOf(box1.items[0..])).Pointer.is_const == false);
var box2: Box2 = .{ .items = undefined };
std.testing.expect(@typeInfo(@TypeOf(box2.items[0..])).Pointer.is_const == false);
}
// const
{
const box0: Box0 = .{ .items = undefined };
std.testing.expect(@typeInfo(@TypeOf(box0.items[0..])).Pointer.is_const == true);
const box1: Box1 = .{ .items = undefined };
std.testing.expect(@typeInfo(@TypeOf(box1.items[0..])).Pointer.is_const == true);
const box2: Box2 = .{ .items = undefined };
std.testing.expect(@typeInfo(@TypeOf(box2.items[0..])).Pointer.is_const == true);
}
}
test "pointer-to-array constness for zero-size elements" {
doTest();
comptime doTest();
}