aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-02-23 12:56:41 -0500
committerAndrew Kelley <superjoe30@gmail.com>2018-02-23 12:56:41 -0500
commit9cfd7dea19c4c54e2754119c04c06cd57cfb759d (patch)
tree3b7950d86f77467b43aa323f80563f678cf6d2fb /src
parent78bc62fd3415dc1db72c916075c9956fdec407aa (diff)
parentb66547e98c9034e52c5647735b47dc24939c8d15 (diff)
downloadzig-9cfd7dea19c4c54e2754119c04c06cd57cfb759d.tar.gz
zig-9cfd7dea19c4c54e2754119c04c06cd57cfb759d.zip
Merge remote-tracking branch 'origin/master' into llvm6
Diffstat (limited to 'src')
-rw-r--r--src/analyze.cpp19
-rw-r--r--src/codegen.cpp2
-rw-r--r--src/ir.cpp85
-rw-r--r--src/tokenizer.cpp2
-rw-r--r--src/tokenizer.hpp1
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,