| ... | @@ -4299,14 +4299,14 @@ static IrInstGen *ir_build_err_to_int_gen(IrAnalyze *ira, Scope *scope, AstNode | ... | @@ -4299,14 +4299,14 @@ static IrInstGen *ir_build_err_to_int_gen(IrAnalyze *ira, Scope *scope, AstNode |
| 4299 | | 4299 | |
| 4300 | static IrInstSrc *ir_build_check_switch_prongs(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, | 4300 | static IrInstSrc *ir_build_check_switch_prongs(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, |
| 4301 | IrInstSrc *target_value, IrInstSrcCheckSwitchProngsRange *ranges, size_t range_count, | 4301 | IrInstSrc *target_value, IrInstSrcCheckSwitchProngsRange *ranges, size_t range_count, |
| 4302 | bool have_else_prong, bool have_underscore_prong) | 4302 | AstNode* else_prong, bool have_underscore_prong) |
| 4303 | { | 4303 | { |
| 4304 | IrInstSrcCheckSwitchProngs *instruction = ir_build_instruction<IrInstSrcCheckSwitchProngs>( | 4304 | IrInstSrcCheckSwitchProngs *instruction = ir_build_instruction<IrInstSrcCheckSwitchProngs>( |
| 4305 | irb, scope, source_node); | 4305 | irb, scope, source_node); |
| 4306 | instruction->target_value = target_value; | 4306 | instruction->target_value = target_value; |
| 4307 | instruction->ranges = ranges; | 4307 | instruction->ranges = ranges; |
| 4308 | instruction->range_count = range_count; | 4308 | instruction->range_count = range_count; |
| 4309 | instruction->have_else_prong = have_else_prong; | 4309 | instruction->else_prong = else_prong; |
| 4310 | instruction->have_underscore_prong = have_underscore_prong; | 4310 | instruction->have_underscore_prong = have_underscore_prong; |
| 4311 | | 4311 | |
| 4312 | ir_ref_instruction(target_value, irb->current_basic_block); | 4312 | ir_ref_instruction(target_value, irb->current_basic_block); |
| ... | @@ -9346,7 +9346,7 @@ static IrInstSrc *ir_gen_switch_expr(IrBuilderSrc *irb, Scope *scope, AstNode *n | ... | @@ -9346,7 +9346,7 @@ static IrInstSrc *ir_gen_switch_expr(IrBuilderSrc *irb, Scope *scope, AstNode *n |
| 9346 | } | 9346 | } |
| 9347 | | 9347 | |
| 9348 | IrInstSrc *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, | 9348 | IrInstSrc *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, |
| 9349 | check_ranges.items, check_ranges.length, else_prong != nullptr, underscore_prong != nullptr); | 9349 | check_ranges.items, check_ranges.length, else_prong, underscore_prong != nullptr); |
| 9350 | | 9350 | |
| 9351 | IrInstSrc *br_instruction; | 9351 | IrInstSrc *br_instruction; |
| 9352 | if (cases.length == 0) { | 9352 | if (cases.length == 0) { |
| ... | @@ -28827,7 +28827,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, | ... | @@ -28827,7 +28827,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, |
| 28827 | buf_ptr(enum_field->name))); | 28827 | buf_ptr(enum_field->name))); |
| 28828 | } | 28828 | } |
| 28829 | } | 28829 | } |
| 28830 | } else if (!instruction->have_else_prong) { | 28830 | } else if (instruction->else_prong == nullptr) { |
| 28831 | if (switch_type->data.enumeration.non_exhaustive) { | 28831 | if (switch_type->data.enumeration.non_exhaustive) { |
| 28832 | ir_add_error(ira, &instruction->base.base, | 28832 | ir_add_error(ira, &instruction->base.base, |
| 28833 | buf_sprintf("switch on non-exhaustive enum must include `else` or `_` prong")); | 28833 | buf_sprintf("switch on non-exhaustive enum must include `else` or `_` prong")); |
| ... | @@ -28842,6 +28842,10 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, | ... | @@ -28842,6 +28842,10 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, |
| 28842 | buf_ptr(enum_field->name))); | 28842 | buf_ptr(enum_field->name))); |
| 28843 | } | 28843 | } |
| 28844 | } | 28844 | } |
| | 28845 | } else if(!switch_type->data.enumeration.non_exhaustive && switch_type->data.enumeration.src_field_count == instruction->range_count) { |
| | 28846 | ir_add_error_node(ira, instruction->else_prong, |
| | 28847 | buf_sprintf("unreachable else prong, all cases already handled")); |
| | 28848 | return ira->codegen->invalid_inst_gen; |
| 28845 | } | 28849 | } |
| 28846 | } else if (switch_type->id == ZigTypeIdErrorSet) { | 28850 | } else if (switch_type->id == ZigTypeIdErrorSet) { |
| 28847 | if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->base.source_node)) { | 28851 | if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->base.source_node)) { |
| ... | @@ -28888,7 +28892,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, | ... | @@ -28888,7 +28892,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, |
| 28888 | } | 28892 | } |
| 28889 | field_prev_uses[start_index] = start_value->base.source_node; | 28893 | field_prev_uses[start_index] = start_value->base.source_node; |
| 28890 | } | 28894 | } |
| 28891 | if (!instruction->have_else_prong) { | 28895 | if (instruction->else_prong == nullptr) { |
| 28892 | if (type_is_global_error_set(switch_type)) { | 28896 | if (type_is_global_error_set(switch_type)) { |
| 28893 | ir_add_error(ira, &instruction->base.base, | 28897 | ir_add_error(ira, &instruction->base.base, |
| 28894 | buf_sprintf("else prong required when switching on type 'anyerror'")); | 28898 | buf_sprintf("else prong required when switching on type 'anyerror'")); |
| ... | @@ -28950,16 +28954,20 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, | ... | @@ -28950,16 +28954,20 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, |
| 28950 | return ira->codegen->invalid_inst_gen; | 28954 | return ira->codegen->invalid_inst_gen; |
| 28951 | } | 28955 | } |
| 28952 | } | 28956 | } |
| 28953 | if (!instruction->have_else_prong) { | 28957 | |
| 28954 | BigInt min_val; | 28958 | BigInt min_val; |
| 28955 | eval_min_max_value_int(ira->codegen, switch_type, &min_val, false); | 28959 | eval_min_max_value_int(ira->codegen, switch_type, &min_val, false); |
| 28956 | BigInt max_val; | 28960 | BigInt max_val; |
| 28957 | eval_min_max_value_int(ira->codegen, switch_type, &max_val, true); | 28961 | eval_min_max_value_int(ira->codegen, switch_type, &max_val, true); |
| 28958 | if (!rangeset_spans(&rs, &min_val, &max_val)) { | 28962 | bool handles_all_cases = rangeset_spans(&rs, &min_val, &max_val); |
| | 28963 | if (!handles_all_cases && instruction->else_prong == nullptr) { |
| 28959 | ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities")); | 28964 | ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities")); |
| 28960 | return ira->codegen->invalid_inst_gen; | 28965 | return ira->codegen->invalid_inst_gen; |
| | 28966 | } else if(handles_all_cases && instruction->else_prong != nullptr) { |
| | 28967 | ir_add_error_node(ira, instruction->else_prong, |
| | 28968 | buf_sprintf("unreachable else prong, all cases already handled")); |
| | 28969 | return ira->codegen->invalid_inst_gen; |
| 28961 | } | 28970 | } |
| 28962 | } | | |
| 28963 | } else if (switch_type->id == ZigTypeIdBool) { | 28971 | } else if (switch_type->id == ZigTypeIdBool) { |
| 28964 | int seenTrue = 0; | 28972 | int seenTrue = 0; |
| 28965 | int seenFalse = 0; | 28973 | int seenFalse = 0; |
| ... | @@ -28989,11 +28997,17 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, | ... | @@ -28989,11 +28997,17 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, |
| 28989 | return ira->codegen->invalid_inst_gen; | 28997 | return ira->codegen->invalid_inst_gen; |
| 28990 | } | 28998 | } |
| 28991 | } | 28999 | } |
| 28992 | if (((seenTrue < 1) || (seenFalse < 1)) && !instruction->have_else_prong) { | 29000 | if (((seenTrue < 1) || (seenFalse < 1)) && instruction->else_prong == nullptr) { |
| 28993 | ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities")); | 29001 | ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities")); |
| 28994 | return ira->codegen->invalid_inst_gen; | 29002 | return ira->codegen->invalid_inst_gen; |
| 28995 | } | 29003 | } |
| 28996 | } else if (!instruction->have_else_prong) { | 29004 | |
| | 29005 | if(seenTrue == 1 && seenFalse == 1 && instruction->else_prong != nullptr) { |
| | 29006 | ir_add_error_node(ira, instruction->else_prong, |
| | 29007 | buf_sprintf("unreachable else prong, all cases already handled")); |
| | 29008 | return ira->codegen->invalid_inst_gen; |
| | 29009 | } |
| | 29010 | } else if (instruction->else_prong == nullptr) { |
| 28997 | ir_add_error(ira, &instruction->base.base, | 29011 | ir_add_error(ira, &instruction->base.base, |
| 28998 | buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name))); | 29012 | buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name))); |
| 28999 | return ira->codegen->invalid_inst_gen; | 29013 | return ira->codegen->invalid_inst_gen; |