aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-08-04 17:09:40 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-08-04 17:09:40 -0700
commitc6e0df6213af1ecf5734bc6bcb4d7c29a4b41351 (patch)
tree42d358704ab86a506d1c53c0fc6da73738560fa7 /src/ir.cpp
parent41a8b6f57b3bd50b2ed6fdced74fba9130eac3d3 (diff)
parentd61a9e37ae8f140407d1369500d21efbe2b198ab (diff)
downloadzig-c6e0df6213af1ecf5734bc6bcb4d7c29a4b41351.tar.gz
zig-c6e0df6213af1ecf5734bc6bcb4d7c29a4b41351.zip
Merge remote-tracking branch 'origin/master' into llvm11
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp74
1 files changed, 58 insertions, 16 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index ff4d06e1db..f93cabcbeb 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -4300,14 +4300,14 @@ static IrInstGen *ir_build_err_to_int_gen(IrAnalyze *ira, Scope *scope, AstNode
static IrInstSrc *ir_build_check_switch_prongs(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
IrInstSrc *target_value, IrInstSrcCheckSwitchProngsRange *ranges, size_t range_count,
- bool have_else_prong, bool have_underscore_prong)
+ AstNode* else_prong, bool have_underscore_prong)
{
IrInstSrcCheckSwitchProngs *instruction = ir_build_instruction<IrInstSrcCheckSwitchProngs>(
irb, scope, source_node);
instruction->target_value = target_value;
instruction->ranges = ranges;
instruction->range_count = range_count;
- instruction->have_else_prong = have_else_prong;
+ instruction->else_prong = else_prong;
instruction->have_underscore_prong = have_underscore_prong;
ir_ref_instruction(target_value, irb->current_basic_block);
@@ -9347,7 +9347,7 @@ static IrInstSrc *ir_gen_switch_expr(IrBuilderSrc *irb, Scope *scope, AstNode *n
}
IrInstSrc *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value,
- check_ranges.items, check_ranges.length, else_prong != nullptr, underscore_prong != nullptr);
+ check_ranges.items, check_ranges.length, else_prong, underscore_prong != nullptr);
IrInstSrc *br_instruction;
if (cases.length == 0) {
@@ -20604,17 +20604,25 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
return ira->codegen->invalid_inst_gen;
}
+ ZigType *expected_return_type = result_loc->value->type->data.pointer.child_type;
+
IrInstGen *dummy_value = ir_const(ira, source_instr, return_type);
dummy_value->value->special = ConstValSpecialRuntime;
IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr,
- dummy_value, result_loc->value->type->data.pointer.child_type);
- if (type_is_invalid(dummy_result->value->type))
+ dummy_value, expected_return_type);
+ if (type_is_invalid(dummy_result->value->type)) {
+ if ((return_type->id == ZigTypeIdErrorUnion || return_type->id == ZigTypeIdErrorSet) &&
+ expected_return_type->id != ZigTypeIdErrorUnion && expected_return_type->id != ZigTypeIdErrorSet)
+ {
+ add_error_note(ira->codegen, ira->new_irb.exec->first_err_trace_msg,
+ ira->explicit_return_type_source_node, buf_create_from_str("function cannot return an error"));
+ }
return ira->codegen->invalid_inst_gen;
- ZigType *res_child_type = result_loc->value->type->data.pointer.child_type;
- if (res_child_type == ira->codegen->builtin_types.entry_anytype) {
- res_child_type = return_type;
}
- if (!handle_is_ptr(ira->codegen, res_child_type)) {
+ if (expected_return_type == ira->codegen->builtin_types.entry_anytype) {
+ expected_return_type = return_type;
+ }
+ if (!handle_is_ptr(ira->codegen, expected_return_type)) {
ir_reset_result(call_result_loc);
result_loc = nullptr;
}
@@ -28828,7 +28836,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
buf_ptr(enum_field->name)));
}
}
- } else if (!instruction->have_else_prong) {
+ } else if (instruction->else_prong == nullptr) {
if (switch_type->data.enumeration.non_exhaustive) {
ir_add_error(ira, &instruction->base.base,
buf_sprintf("switch on non-exhaustive enum must include `else` or `_` prong"));
@@ -28843,6 +28851,10 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
buf_ptr(enum_field->name)));
}
}
+ } else if(!switch_type->data.enumeration.non_exhaustive && switch_type->data.enumeration.src_field_count == instruction->range_count) {
+ ir_add_error_node(ira, instruction->else_prong,
+ buf_sprintf("unreachable else prong, all cases already handled"));
+ return ira->codegen->invalid_inst_gen;
}
} else if (switch_type->id == ZigTypeIdErrorSet) {
if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->base.source_node)) {
@@ -28889,7 +28901,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
}
field_prev_uses[start_index] = start_value->base.source_node;
}
- if (!instruction->have_else_prong) {
+ if (instruction->else_prong == nullptr) {
if (type_is_global_error_set(switch_type)) {
ir_add_error(ira, &instruction->base.base,
buf_sprintf("else prong required when switching on type 'anyerror'"));
@@ -28951,16 +28963,20 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
return ira->codegen->invalid_inst_gen;
}
}
- if (!instruction->have_else_prong) {
+
BigInt min_val;
eval_min_max_value_int(ira->codegen, switch_type, &min_val, false);
BigInt max_val;
eval_min_max_value_int(ira->codegen, switch_type, &max_val, true);
- if (!rangeset_spans(&rs, &min_val, &max_val)) {
+ bool handles_all_cases = rangeset_spans(&rs, &min_val, &max_val);
+ if (!handles_all_cases && instruction->else_prong == nullptr) {
ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities"));
return ira->codegen->invalid_inst_gen;
+ } else if(handles_all_cases && instruction->else_prong != nullptr) {
+ ir_add_error_node(ira, instruction->else_prong,
+ buf_sprintf("unreachable else prong, all cases already handled"));
+ return ira->codegen->invalid_inst_gen;
}
- }
} else if (switch_type->id == ZigTypeIdBool) {
int seenTrue = 0;
int seenFalse = 0;
@@ -28990,11 +29006,17 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
return ira->codegen->invalid_inst_gen;
}
}
- if (((seenTrue < 1) || (seenFalse < 1)) && !instruction->have_else_prong) {
+ if (((seenTrue < 1) || (seenFalse < 1)) && instruction->else_prong == nullptr) {
ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities"));
return ira->codegen->invalid_inst_gen;
}
- } else if (!instruction->have_else_prong) {
+
+ if(seenTrue == 1 && seenFalse == 1 && instruction->else_prong != nullptr) {
+ ir_add_error_node(ira, instruction->else_prong,
+ buf_sprintf("unreachable else prong, all cases already handled"));
+ return ira->codegen->invalid_inst_gen;
+ }
+ } else if (instruction->else_prong == nullptr) {
ir_add_error(ira, &instruction->base.base,
buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name)));
return ira->codegen->invalid_inst_gen;
@@ -29077,6 +29099,19 @@ static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t alig
ZigType *result_type;
uint32_t old_align_bytes;
+ ZigType *actual_ptr = target_type;
+ if (actual_ptr->id == ZigTypeIdOptional) {
+ actual_ptr = actual_ptr->data.maybe.child_type;
+ } else if (is_slice(actual_ptr)) {
+ actual_ptr = actual_ptr->data.structure.fields[slice_ptr_index]->type_entry;
+ }
+
+ if (safety_check_on && !type_has_bits(ira->codegen, actual_ptr)) {
+ ir_add_error(ira, &target->base,
+ buf_sprintf("cannot adjust alignment of zero sized type '%s'", buf_ptr(&target_type->name)));
+ return ira->codegen->invalid_inst_gen;
+ }
+
if (target_type->id == ZigTypeIdPointer) {
result_type = adjust_ptr_align(ira->codegen, target_type, align_bytes);
if ((err = resolve_ptr_align(ira, target_type, &old_align_bytes)))
@@ -30894,6 +30929,13 @@ static IrInstGen *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstSrcEndEx
IrInstGen *store_ptr = ir_analyze_store_ptr(ira, &instruction->base.base, result_loc, value,
instruction->result_loc->allow_write_through_const);
if (type_is_invalid(store_ptr->value->type)) {
+ if (instruction->result_loc->id == ResultLocIdReturn &&
+ (value->value->type->id == ZigTypeIdErrorUnion || value->value->type->id == ZigTypeIdErrorSet) &&
+ ira->explicit_return_type->id != ZigTypeIdErrorUnion && ira->explicit_return_type->id != ZigTypeIdErrorSet)
+ {
+ add_error_note(ira->codegen, ira->new_irb.exec->first_err_trace_msg,
+ ira->explicit_return_type_source_node, buf_create_from_str("function cannot return an error"));
+ }
return ira->codegen->invalid_inst_gen;
}
}