diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/analyze.cpp | 4 | ||||
| -rw-r--r-- | src/ir.cpp | 24 |
2 files changed, 26 insertions, 2 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 235aeea682..7d51e83677 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1399,6 +1399,10 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { enum_type->data.enumeration.is_invalid = true; add_node_error(g, decl_node->data.container_decl.init_arg_expr, buf_sprintf("expected integer, found '%s'", buf_ptr(&wanted_tag_int_type->name))); + } else if (wanted_tag_int_type->data.integral.is_signed) { + enum_type->data.enumeration.is_invalid = true; + add_node_error(g, decl_node->data.container_decl.init_arg_expr, + buf_sprintf("expected unsigned integer, found '%s'", buf_ptr(&wanted_tag_int_type->name))); } else if (wanted_tag_int_type->data.integral.bit_count < tag_int_type->data.integral.bit_count) { enum_type->data.enumeration.is_invalid = true; add_node_error(g, decl_node->data.container_decl.init_arg_expr, diff --git a/src/ir.cpp b/src/ir.cpp index c8617e3a8a..c6003fbf32 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -8911,7 +8911,17 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst wanted_type->id == TypeTableEntryIdEnum && wanted_type->data.enumeration.gen_field_count == 0) { - return ir_analyze_int_to_enum(ira, source_instr, value, wanted_type); + ensure_complete_type(ira->codegen, wanted_type); + if (type_is_invalid(wanted_type)) + return ira->codegen->invalid_instruction; + if (actual_type == wanted_type->data.enumeration.tag_type->data.enum_tag.int_type) { + return ir_analyze_int_to_enum(ira, source_instr, value, wanted_type); + } + ir_add_error(ira, source_instr, + buf_sprintf("integer to enum cast from '%s' instead of its tag type, '%s'", + buf_ptr(&actual_type->name), + buf_ptr(&wanted_type->data.enumeration.tag_type->data.enum_tag.int_type->name))); + return ira->codegen->invalid_instruction; } // explicit cast from enum type with no payload to integer @@ -8919,7 +8929,17 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst actual_type->id == TypeTableEntryIdEnum && actual_type->data.enumeration.gen_field_count == 0) { - return ir_analyze_enum_to_int(ira, source_instr, value, wanted_type); + ensure_complete_type(ira->codegen, actual_type); + if (type_is_invalid(actual_type)) + return ira->codegen->invalid_instruction; + if (wanted_type == actual_type->data.enumeration.tag_type->data.enum_tag.int_type) { + return ir_analyze_enum_to_int(ira, source_instr, value, wanted_type); + } + ir_add_error(ira, source_instr, + buf_sprintf("enum to integer cast to '%s' instead of its tag type, '%s'", + buf_ptr(&wanted_type->name), + buf_ptr(&actual_type->data.enumeration.tag_type->data.enum_tag.int_type->name))); + return ira->codegen->invalid_instruction; } // explicit cast from undefined to anything |
