diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-02-23 12:56:41 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-02-23 12:56:41 -0500 |
| commit | 9cfd7dea19c4c54e2754119c04c06cd57cfb759d (patch) | |
| tree | 3b7950d86f77467b43aa323f80563f678cf6d2fb /src | |
| parent | 78bc62fd3415dc1db72c916075c9956fdec407aa (diff) | |
| parent | b66547e98c9034e52c5647735b47dc24939c8d15 (diff) | |
| download | zig-9cfd7dea19c4c54e2754119c04c06cd57cfb759d.tar.gz zig-9cfd7dea19c4c54e2754119c04c06cd57cfb759d.zip | |
Merge remote-tracking branch 'origin/master' into llvm6
Diffstat (limited to 'src')
| -rw-r--r-- | src/analyze.cpp | 19 | ||||
| -rw-r--r-- | src/codegen.cpp | 2 | ||||
| -rw-r--r-- | src/ir.cpp | 85 | ||||
| -rw-r--r-- | src/tokenizer.cpp | 2 | ||||
| -rw-r--r-- | src/tokenizer.hpp | 1 |
5 files changed, 68 insertions, 41 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index bf7b6e363f..c16a5d462a 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2278,17 +2278,16 @@ static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) { return; if (struct_type->data.structure.zero_bits_loop_flag) { - // If we get here it's due to recursion. From this we conclude that the struct is - // not zero bits, and if abi_alignment == 0 we further conclude that the first field - // is a pointer to this very struct, or a function pointer with parameters that - // reference such a type. + // If we get here it's due to recursion. This is a design flaw in the compiler, + // we should be able to still figure out alignment, but here we give up and say that + // the alignment is pointer width, then assert that the first field is within that + // alignment struct_type->data.structure.zero_bits_known = true; if (struct_type->data.structure.abi_alignment == 0) { if (struct_type->data.structure.layout == ContainerLayoutPacked) { struct_type->data.structure.abi_alignment = 1; } else { - struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, - LLVMPointerType(LLVMInt8Type(), 0)); + struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, LLVMPointerType(LLVMInt8Type(), 0)); } } return; @@ -2352,11 +2351,17 @@ static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) { if (gen_field_index == 0) { if (struct_type->data.structure.layout == ContainerLayoutPacked) { struct_type->data.structure.abi_alignment = 1; - } else { + } else if (struct_type->data.structure.abi_alignment == 0) { // Alignment of structs is the alignment of the first field, for now. // TODO change this when we re-order struct fields (issue #168) struct_type->data.structure.abi_alignment = get_abi_alignment(g, field_type); assert(struct_type->data.structure.abi_alignment != 0); + } else { + // due to a design flaw in the compiler we assumed that alignment was + // pointer width, so we assert that this wasn't violated. + if (get_abi_alignment(g, field_type) > struct_type->data.structure.abi_alignment) { + zig_panic("compiler design flaw: incorrect alignment assumption"); + } } } diff --git a/src/codegen.cpp b/src/codegen.cpp index 4f100d75ad..15648cbdec 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4201,6 +4201,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c continue; } ConstExprValue *field_val = &const_val->data.x_struct.fields[i]; + assert(field_val->type != nullptr); LLVMValueRef val = gen_const_val(g, field_val, ""); fields[type_struct_field->gen_index] = val; make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(field_val->type, val); @@ -4373,6 +4374,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c } } } + zig_unreachable(); case TypeTableEntryIdErrorUnion: { TypeTableEntry *payload_type = type_entry->data.error_union.payload_type; diff --git a/src/ir.cpp b/src/ir.cpp index 2bb40c7e15..b276abff33 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4172,7 +4172,13 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol))); } + // Temporarily set the name of the IrExecutable to the VariableDeclaration + // so that the struct or enum from the init expression inherits the name. + Buf *old_exec_name = irb->exec->name; + irb->exec->name = variable_declaration->symbol; IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope); + irb->exec->name = old_exec_name; + if (init_value == irb->codegen->invalid_instruction) return init_value; @@ -6727,8 +6733,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry result.id = ConstCastResultIdFnReturnType; result.data.return_type = allocate_nonzero<ConstCastOnly>(1); *result.data.return_type = child; + return result; } - return result; } if (expected_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { result.id = ConstCastResultIdFnArgCount; @@ -8183,7 +8189,7 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi } if (instr_is_comptime(value)) { - ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); + ConstExprValue *val = ir_resolve_const(ira, value, UndefOk); if (!val) return ira->codegen->invalid_instruction; bool final_is_const = (value->value.type->id == TypeTableEntryIdMetaType) ? is_const : true; @@ -9975,15 +9981,18 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ; } } else { - if (float_cmp_zero(&op2->value) == CmpEQ) { + IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); + if (casted_op2 == ira->codegen->invalid_instruction) + return ira->codegen->builtin_types.entry_invalid; + if (float_cmp_zero(&casted_op2->value) == CmpEQ) { // the division by zero error will be caught later, but we don't // have a remainder function ambiguity problem ok = true; } else { ConstExprValue rem_result; ConstExprValue mod_result; - float_rem(&rem_result, &op1->value, &op2->value); - float_mod(&mod_result, &op1->value, &op2->value); + float_rem(&rem_result, &op1->value, &casted_op2->value); + float_mod(&mod_result, &op1->value, &casted_op2->value); ok = float_cmp(&rem_result, &mod_result) == CmpEQ; } } @@ -14928,6 +14937,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio ConstExprValue *parent_ptr; size_t abs_offset; size_t rel_end; + bool ptr_is_undef = false; if (array_type->id == TypeTableEntryIdArray) { array_val = const_ptr_pointee(ira->codegen, &ptr_ptr->value); abs_offset = 0; @@ -14935,7 +14945,12 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio parent_ptr = nullptr; } else if (array_type->id == TypeTableEntryIdPointer) { parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value); - switch (parent_ptr->data.x_ptr.special) { + if (parent_ptr->special == ConstValSpecialUndef) { + array_val = nullptr; + abs_offset = 0; + rel_end = SIZE_MAX; + ptr_is_undef = true; + } else switch (parent_ptr->data.x_ptr.special) { case ConstPtrSpecialInvalid: case ConstPtrSpecialDiscard: zig_unreachable(); @@ -14989,7 +15004,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio } uint64_t start_scalar = bigint_as_unsigned(&casted_start->value.data.x_bigint); - if (start_scalar > rel_end) { + if (!ptr_is_undef && start_scalar > rel_end) { ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); return ira->codegen->builtin_types.entry_invalid; } @@ -15000,12 +15015,18 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio } else { end_scalar = rel_end; } - if (end_scalar > rel_end) { - ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); - return ira->codegen->builtin_types.entry_invalid; + if (!ptr_is_undef) { + if (end_scalar > rel_end) { + ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); + return ira->codegen->builtin_types.entry_invalid; + } + if (start_scalar > end_scalar) { + ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); + return ira->codegen->builtin_types.entry_invalid; + } } - if (start_scalar > end_scalar) { - ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); + if (ptr_is_undef && start_scalar != end_scalar) { + ir_add_error(ira, &instruction->base, buf_sprintf("non-zero length slice of undefined pointer")); return ira->codegen->builtin_types.entry_invalid; } @@ -15021,25 +15042,27 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio if (array_type->id == TypeTableEntryIdArray) { ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut; } - } else { - switch (parent_ptr->data.x_ptr.special) { - case ConstPtrSpecialInvalid: - case ConstPtrSpecialDiscard: - zig_unreachable(); - case ConstPtrSpecialRef: - init_const_ptr_ref(ira->codegen, ptr_val, - parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type)); - break; - case ConstPtrSpecialBaseArray: - zig_unreachable(); - case ConstPtrSpecialBaseStruct: - zig_panic("TODO"); - case ConstPtrSpecialHardCodedAddr: - init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, - parent_ptr->type->data.pointer.child_type, - parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, - slice_is_const(return_type)); - } + } else if (ptr_is_undef) { + ptr_val->type = get_pointer_to_type(ira->codegen, parent_ptr->type->data.pointer.child_type, + slice_is_const(return_type)); + ptr_val->special = ConstValSpecialUndef; + } else switch (parent_ptr->data.x_ptr.special) { + case ConstPtrSpecialInvalid: + case ConstPtrSpecialDiscard: + zig_unreachable(); + case ConstPtrSpecialRef: + init_const_ptr_ref(ira->codegen, ptr_val, + parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type)); + break; + case ConstPtrSpecialBaseArray: + zig_unreachable(); + case ConstPtrSpecialBaseStruct: + zig_panic("TODO"); + case ConstPtrSpecialHardCodedAddr: + init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, + parent_ptr->type->data.pointer.child_type, + parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, + slice_is_const(return_type)); } ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index]; diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 44d838a723..dd60815b7f 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -125,7 +125,6 @@ static const struct ZigKeyword zig_keywords[] = { {"false", TokenIdKeywordFalse}, {"fn", TokenIdKeywordFn}, {"for", TokenIdKeywordFor}, - {"goto", TokenIdKeywordGoto}, {"if", TokenIdKeywordIf}, {"inline", TokenIdKeywordInline}, {"nakedcc", TokenIdKeywordNakedCC}, @@ -1542,7 +1541,6 @@ const char * token_name(TokenId id) { case TokenIdKeywordFalse: return "false"; case TokenIdKeywordFn: return "fn"; case TokenIdKeywordFor: return "for"; - case TokenIdKeywordGoto: return "goto"; case TokenIdKeywordIf: return "if"; case TokenIdKeywordInline: return "inline"; case TokenIdKeywordNakedCC: return "nakedcc"; diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp index 92a3b8de0d..225b75d844 100644 --- a/src/tokenizer.hpp +++ b/src/tokenizer.hpp @@ -66,7 +66,6 @@ enum TokenId { TokenIdKeywordFalse, TokenIdKeywordFn, TokenIdKeywordFor, - TokenIdKeywordGoto, TokenIdKeywordIf, TokenIdKeywordInline, TokenIdKeywordNakedCC, |
