Replace unreachable() with assert(false)
This commit is contained in:
@ -148,7 +148,7 @@ namespace elna::gcc
|
||||
if (!is_assignable_from(TREE_VALUE(current_parameter), this->current_expression))
|
||||
{
|
||||
error_at(argument_location,
|
||||
"cannot assign value of type '%s' to variable of type '%s'",
|
||||
"Cannot assign value of type '%s' to variable of type '%s'",
|
||||
print_type(TREE_TYPE(this->current_expression)).c_str(),
|
||||
print_type(TREE_VALUE(current_parameter)).c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
@ -202,7 +202,7 @@ namespace elna::gcc
|
||||
}
|
||||
if (!is_void_type(record_fields))
|
||||
{
|
||||
error_at(call_location, "too few arguments, expected %i, got %lu",
|
||||
error_at(call_location, "Too few arguments, expected %i, got %lu",
|
||||
list_length(TYPE_FIELDS(symbol)), arguments.size());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
@ -212,8 +212,62 @@ namespace elna::gcc
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::build_assert_builtin(location_t call_location,
|
||||
const std::vector<boot::expression *>& arguments)
|
||||
{
|
||||
if (arguments.size() != 1)
|
||||
{
|
||||
error_at(call_location, "assert expects exactly one boolean argument, got %lu", arguments.size());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
arguments.at(0)->accept(this);
|
||||
tree argument_type = TREE_TYPE(this->current_expression);
|
||||
|
||||
if (argument_type != elna_bool_type_node)
|
||||
{
|
||||
error_at(call_location, "assert expects exactly one boolean argument, got %s",
|
||||
print_type(argument_type).c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
tree constant_expression = extract_constant(this->current_expression);
|
||||
if (constant_expression == boolean_false_node)
|
||||
{
|
||||
this->current_expression = call_built_in(call_location, "__builtin_unreachable", void_type_node);
|
||||
}
|
||||
else if (constant_expression != boolean_true_node)
|
||||
{
|
||||
this->current_expression = call_built_in(call_location, "__builtin_trap", void_type_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool generic_visitor::build_builtin_procedures(boot::procedure_call *call)
|
||||
{
|
||||
location_t call_location = get_location(&call->position());
|
||||
|
||||
if (boot::variable_expression *named_call = call->callable().is_variable())
|
||||
{
|
||||
if (named_call->name == "assert")
|
||||
{
|
||||
build_assert_builtin(call_location, call->arguments);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::procedure_call *call)
|
||||
{
|
||||
if (build_builtin_procedures(call))
|
||||
{
|
||||
return;
|
||||
}
|
||||
location_t call_location = get_location(&call->position());
|
||||
call->callable().accept(this);
|
||||
|
||||
@ -599,13 +653,8 @@ namespace elna::gcc
|
||||
right, elna_string_ptr_field_node, NULL_TREE);
|
||||
|
||||
tree length_equality = build2(equality_code, elna_bool_type_node, lhs_length, rhs_length);
|
||||
tree *memcmp = elna_global_decls->get("__builtin_memcmp");
|
||||
gcc_assert(memcmp != nullptr);
|
||||
|
||||
tree fndecl_type = build_function_type(integer_type_node, TYPE_ARG_TYPES(*memcmp));
|
||||
tree memcmp_addr = build1(ADDR_EXPR, build_pointer_type(fndecl_type), *memcmp);
|
||||
tree memcmp_call = build_call_nary(integer_type_node, memcmp_addr, 3, lhs_ptr, rhs_ptr, lhs_length);
|
||||
|
||||
tree memcmp_call = call_built_in(UNKNOWN_LOCATION, "__builtin_memcmp", integer_type_node,
|
||||
lhs_ptr, rhs_ptr, lhs_length);
|
||||
tree equals_zero = build2(equality_code, elna_bool_type_node, memcmp_call, integer_zero_node);
|
||||
|
||||
return build2(combination_code, elna_bool_type_node, length_equality, equals_zero);
|
||||
@ -768,7 +817,7 @@ namespace elna::gcc
|
||||
location_t definition_location = get_location(&definition->position());
|
||||
definition->body().accept(this);
|
||||
|
||||
if (extract_constant(definition_location))
|
||||
if (assert_constant(definition_location))
|
||||
{
|
||||
this->current_expression = fold_init(this->current_expression);
|
||||
}
|
||||
@ -1490,7 +1539,7 @@ namespace elna::gcc
|
||||
case_label->accept(this);
|
||||
location_t case_location = get_location(&case_label->position());
|
||||
|
||||
if (extract_constant(case_location)
|
||||
if (assert_constant(case_location)
|
||||
&& !is_assignable_from(unqualified_condition, this->current_expression))
|
||||
{
|
||||
error_at(case_location, "Case type '%s' does not match the expression type '%s'",
|
||||
@ -1535,20 +1584,19 @@ namespace elna::gcc
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
|
||||
bool generic_visitor::extract_constant(location_t expression_location)
|
||||
bool generic_visitor::assert_constant(location_t expression_location)
|
||||
{
|
||||
int code = TREE_CODE(this->current_expression);
|
||||
tree constant_expression = extract_constant(this->current_expression);
|
||||
|
||||
if (code == CONST_DECL)
|
||||
{
|
||||
this->current_expression = DECL_INITIAL(this->current_expression);
|
||||
}
|
||||
else if (TREE_CODE_CLASS(code) != tcc_constant)
|
||||
if (constant_expression == NULL_TREE)
|
||||
{
|
||||
error_at(expression_location, "Expected a constant expression");
|
||||
this->current_expression = error_mark_node;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
else
|
||||
{
|
||||
this->current_expression = constant_expression;
|
||||
}
|
||||
return this->current_expression != error_mark_node;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user