authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-12 21:34:06-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-12 21:57:25-05:00
log32b37e695aa0581b863a395e0a28b7b4aa76c07d
tree6c942241282c9c1163bb22b75f91efda49712291
parent37318bf15138d0a7b158b32ca43cbcdcf5382942
signaturelock-open Commit is signed but in an unrecognized format.

fix anonymous struct literal assigned to variable

closes #3667

5 files changed, 49 insertions(+), 11 deletions(-)

src/analyze.cpp+22-1
...@@ -5432,7 +5432,7 @@ bool fn_eval_eql(Scope *a, Scope *b) {...@@ -5432,7 +5432,7 @@ bool fn_eval_eql(Scope *a, Scope *b) {
5432 return false;5432 return false;
5433}5433}
54345434
5435// Whether the type has bits at runtime.5435// Deprecated. Use type_has_bits2.
5436bool type_has_bits(ZigType *type_entry) {5436bool type_has_bits(ZigType *type_entry) {
5437 assert(type_entry != nullptr);5437 assert(type_entry != nullptr);
5438 assert(!type_is_invalid(type_entry));5438 assert(!type_is_invalid(type_entry));
...@@ -5440,6 +5440,27 @@ bool type_has_bits(ZigType *type_entry) {...@@ -5440,6 +5440,27 @@ bool type_has_bits(ZigType *type_entry) {
5440 return type_entry->abi_size != 0;5440 return type_entry->abi_size != 0;
5441}5441}
54425442
5443// Whether the type has bits at runtime.
5444Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result) {
5445 Error err;
5446
5447 if (type_is_invalid(type_entry))
5448 return ErrorSemanticAnalyzeFail;
5449
5450 if (type_entry->id == ZigTypeIdStruct &&
5451 type_entry->data.structure.resolve_status == ResolveStatusBeingInferred)
5452 {
5453 *result = true;
5454 return ErrorNone;
5455 }
5456
5457 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
5458 return err;
5459
5460 *result = type_entry->abi_size != 0;
5461 return ErrorNone;
5462}
5463
5443// Whether you can infer the value based solely on the type.5464// Whether you can infer the value based solely on the type.
5444OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {5465OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
5445 assert(type_entry != nullptr);5466 assert(type_entry != nullptr);
src/analyze.hpp+2
...@@ -46,6 +46,8 @@ ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);...@@ -46,6 +46,8 @@ ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
46bool handle_is_ptr(ZigType *type_entry);46bool handle_is_ptr(ZigType *type_entry);
4747
48bool type_has_bits(ZigType *type_entry);48bool type_has_bits(ZigType *type_entry);
49Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result);
50
49Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result);51Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result);
50bool ptr_allows_addr_zero(ZigType *ptr_type);52bool ptr_allows_addr_zero(ZigType *ptr_type);
51bool type_is_nonnull_ptr(ZigType *type);53bool type_is_nonnull_ptr(ZigType *type);
src/codegen.cpp+6-1
...@@ -3622,9 +3622,14 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_...@@ -3622,9 +3622,14 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_
3622}3622}
36233623
3624static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {3624static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {
3625 Error err;
3626
3625 ZigType *ptr_type = instruction->ptr->value.type;3627 ZigType *ptr_type = instruction->ptr->value.type;
3626 assert(ptr_type->id == ZigTypeIdPointer);3628 assert(ptr_type->id == ZigTypeIdPointer);
3627 if (!type_has_bits(ptr_type))3629 bool ptr_type_has_bits;
3630 if ((err = type_has_bits2(g, ptr_type, &ptr_type_has_bits)))
3631 codegen_report_errors_and_exit(g);
3632 if (!ptr_type_has_bits)
3628 return nullptr;3633 return nullptr;
3629 if (instruction->ptr->ref_count == 0) {3634 if (instruction->ptr->ref_count == 0) {
3630 // In this case, this StorePtr instruction should be elided. Something happened like this:3635 // In this case, this StorePtr instruction should be elided. Something happened like this:
src/ir.cpp+9-8
...@@ -15513,15 +15513,16 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in...@@ -15513,15 +15513,16 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in
15513 result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer;15513 result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer;
15514 result->base.value.data.x_ptr.data.ref.pointee = pointee;15514 result->base.value.data.x_ptr.data.ref.pointee = pointee;
1551515515
15516 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown)))15516 bool var_type_has_bits;
15517 if ((err = type_has_bits2(ira->codegen, var_type, &var_type_has_bits)))
15517 return ira->codegen->invalid_instruction;15518 return ira->codegen->invalid_instruction;
15518 if (align != 0) {15519 if (align != 0) {
15519 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown)))15520 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown)))
15520 return ira->codegen->invalid_instruction;15521 return ira->codegen->invalid_instruction;
15521 if (!type_has_bits(var_type)) {15522 if (!var_type_has_bits) {
15522 ir_add_error(ira, source_inst,15523 ir_add_error(ira, source_inst,
15523 buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned",15524 buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned",
15524 name_hint, buf_ptr(&var_type->name)));15525 name_hint, buf_ptr(&var_type->name)));
15525 return ira->codegen->invalid_instruction;15526 return ira->codegen->invalid_instruction;
15526 }15527 }
15527 }15528 }
...@@ -22138,15 +22139,15 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct...@@ -22138,15 +22139,15 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
22138 }22139 }
22139 for (size_t i = 0; i < errors_len; i += 1) {22140 for (size_t i = 0; i < errors_len; i += 1) {
22140 Stage2ErrorMsg *clang_err = &errors_ptr[i];22141 Stage2ErrorMsg *clang_err = &errors_ptr[i];
22141 // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null22142 // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null
22142 if (clang_err->source && clang_err->filename_ptr) {22143 if (clang_err->source && clang_err->filename_ptr) {
22143 ErrorMsg *err_msg = err_msg_create_with_offset(22144 ErrorMsg *err_msg = err_msg_create_with_offset(
22144 clang_err->filename_ptr ?22145 clang_err->filename_ptr ?
22145 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),22146 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
22146 clang_err->line, clang_err->column, clang_err->offset, clang_err->source,22147 clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
22147 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));22148 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
22148 err_msg_add_note(parent_err_msg, err_msg);22149 err_msg_add_note(parent_err_msg, err_msg);
22149 }22150 }
22150 }22151 }
2215122152
22152 return ira->codegen->invalid_instruction;22153 return ira->codegen->invalid_instruction;
test/stage1/behavior/struct.zig+10-1
...@@ -755,7 +755,7 @@ test "fully anonymous struct" {...@@ -755,7 +755,7 @@ test "fully anonymous struct" {
755test "fully anonymous list literal" {755test "fully anonymous list literal" {
756 const S = struct {756 const S = struct {
757 fn doTheTest() void {757 fn doTheTest() void {
758 dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi"});758 dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
759 }759 }
760 fn dump(args: var) void {760 fn dump(args: var) void {
761 expect(args.@"0" == 1234);761 expect(args.@"0" == 1234);
...@@ -768,3 +768,12 @@ test "fully anonymous list literal" {...@@ -768,3 +768,12 @@ test "fully anonymous list literal" {
768 S.doTheTest();768 S.doTheTest();
769 comptime S.doTheTest();769 comptime S.doTheTest();
770}770}
771
772test "anonymous struct literal assigned to variable" {
773 var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) };
774 expect(vec.@"0" == 22);
775 expect(vec.@"1" == 55);
776 expect(vec.@"2" == 99);
777 vec.@"1" += 1;
778 expect(vec.@"1" == 56);
779}