fix anonymous struct literal assigned to variable

closes #3667
This commit is contained in:
Andrew Kelley 2019-11-12 21:34:06 -05:00
parent 37318bf151
commit 32b37e695a
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
5 changed files with 49 additions and 11 deletions

View File

@ -5432,7 +5432,7 @@ bool fn_eval_eql(Scope *a, Scope *b) {
return false;
}
// Whether the type has bits at runtime.
// Deprecated. Use type_has_bits2.
bool type_has_bits(ZigType *type_entry) {
assert(type_entry != nullptr);
assert(!type_is_invalid(type_entry));
@ -5440,6 +5440,27 @@ bool type_has_bits(ZigType *type_entry) {
return type_entry->abi_size != 0;
}
// Whether the type has bits at runtime.
Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result) {
Error err;
if (type_is_invalid(type_entry))
return ErrorSemanticAnalyzeFail;
if (type_entry->id == ZigTypeIdStruct &&
type_entry->data.structure.resolve_status == ResolveStatusBeingInferred)
{
*result = true;
return ErrorNone;
}
if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
return err;
*result = type_entry->abi_size != 0;
return ErrorNone;
}
// Whether you can infer the value based solely on the type.
OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
assert(type_entry != nullptr);

View File

@ -46,6 +46,8 @@ ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
bool handle_is_ptr(ZigType *type_entry);
bool type_has_bits(ZigType *type_entry);
Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result);
Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result);
bool ptr_allows_addr_zero(ZigType *ptr_type);
bool type_is_nonnull_ptr(ZigType *type);

View File

@ -3622,9 +3622,14 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_
}
static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {
Error err;
ZigType *ptr_type = instruction->ptr->value.type;
assert(ptr_type->id == ZigTypeIdPointer);
if (!type_has_bits(ptr_type))
bool ptr_type_has_bits;
if ((err = type_has_bits2(g, ptr_type, &ptr_type_has_bits)))
codegen_report_errors_and_exit(g);
if (!ptr_type_has_bits)
return nullptr;
if (instruction->ptr->ref_count == 0) {
// In this case, this StorePtr instruction should be elided. Something happened like this:

View File

@ -15513,15 +15513,16 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in
result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer;
result->base.value.data.x_ptr.data.ref.pointee = pointee;
if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown)))
bool var_type_has_bits;
if ((err = type_has_bits2(ira->codegen, var_type, &var_type_has_bits)))
return ira->codegen->invalid_instruction;
if (align != 0) {
if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown)))
return ira->codegen->invalid_instruction;
if (!type_has_bits(var_type)) {
ir_add_error(ira, source_inst,
buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned",
name_hint, buf_ptr(&var_type->name)));
if (!var_type_has_bits) {
ir_add_error(ira, source_inst,
buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned",
name_hint, buf_ptr(&var_type->name)));
return ira->codegen->invalid_instruction;
}
}
@ -22138,15 +22139,15 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
}
for (size_t i = 0; i < errors_len; i += 1) {
Stage2ErrorMsg *clang_err = &errors_ptr[i];
// Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null
if (clang_err->source && clang_err->filename_ptr) {
// Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null
if (clang_err->source && clang_err->filename_ptr) {
ErrorMsg *err_msg = err_msg_create_with_offset(
clang_err->filename_ptr ?
buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
err_msg_add_note(parent_err_msg, err_msg);
}
}
}
return ira->codegen->invalid_instruction;

View File

@ -755,7 +755,7 @@ test "fully anonymous struct" {
test "fully anonymous list literal" {
const S = struct {
fn doTheTest() void {
dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi"});
dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
}
fn dump(args: var) void {
expect(args.@"0" == 1234);
@ -768,3 +768,12 @@ test "fully anonymous list literal" {
S.doTheTest();
comptime S.doTheTest();
}
test "anonymous struct literal assigned to variable" {
var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) };
expect(vec.@"0" == 22);
expect(vec.@"1" == 55);
expect(vec.@"2" == 99);
vec.@"1" += 1;
expect(vec.@"1" == 56);
}