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) {
54325432 return false;
54335433}
54345434
5435// Whether the type has bits at runtime.
5435// Deprecated. Use type_has_bits2.
54365436bool type_has_bits(ZigType *type_entry) {
54375437 assert(type_entry != nullptr);
54385438 assert(!type_is_invalid(type_entry));
......@@ -5440,6 +5440,27 @@ bool type_has_bits(ZigType *type_entry) {
54405440 return type_entry->abi_size != 0;
54415441}
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
54435464// Whether you can infer the value based solely on the type.
54445465OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
54455466 assert(type_entry != nullptr);
src/analyze.hpp+2
......@@ -46,6 +46,8 @@ ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
4646bool handle_is_ptr(ZigType *type_entry);
4747
4848bool type_has_bits(ZigType *type_entry);
49Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result);
50
4951Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result);
5052bool ptr_allows_addr_zero(ZigType *ptr_type);
5153bool 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_
36223622}
36233623
36243624static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {
3625 Error err;
3626
36253627 ZigType *ptr_type = instruction->ptr->value.type;
36263628 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)
36283633 return nullptr;
36293634 if (instruction->ptr->ref_count == 0) {
36303635 // 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
1551315513 result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer;
1551415514 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)))
1551715518 return ira->codegen->invalid_instruction;
1551815519 if (align != 0) {
1551915520 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown)))
1552015521 return ira->codegen->invalid_instruction;
15521 if (!type_has_bits(var_type)) {
15522 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 name_hint, buf_ptr(&var_type->name)));
15522 if (!var_type_has_bits) {
15523 ir_add_error(ira, source_inst,
15524 buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned",
15525 name_hint, buf_ptr(&var_type->name)));
1552515526 return ira->codegen->invalid_instruction;
1552615527 }
1552715528 }
......@@ -22138,15 +22139,15 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
2213822139 }
2213922140 for (size_t i = 0; i < errors_len; i += 1) {
2214022141 Stage2ErrorMsg *clang_err = &errors_ptr[i];
22141 // 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) {
22142 // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null
22143 if (clang_err->source && clang_err->filename_ptr) {
2214322144 ErrorMsg *err_msg = err_msg_create_with_offset(
2214422145 clang_err->filename_ptr ?
2214522146 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
2214622147 clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
2214722148 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
2214822149 err_msg_add_note(parent_err_msg, err_msg);
22149 }
22150 }
2215022151 }
2215122152
2215222153 return ira->codegen->invalid_instruction;
test/stage1/behavior/struct.zig+10-1
......@@ -755,7 +755,7 @@ test "fully anonymous struct" {
755755test "fully anonymous list literal" {
756756 const S = struct {
757757 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" });
759759 }
760760 fn dump(args: var) void {
761761 expect(args.@"0" == 1234);
......@@ -768,3 +768,12 @@ test "fully anonymous list literal" {
768768 S.doTheTest();
769769 comptime S.doTheTest();
770770}
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}