Skip to content

Commit

Permalink
Conditional allocations shouldn't fail for size=0 in C++ backend (#7255)
Browse files Browse the repository at this point in the history
Allocations can be conditional; if the condition evaluates to false, we end up calling `halide_malloc(0)` (or `halide_tcm_malloc(0)` in the xtensa branch). Since it's legal via spec for `malloc(0)` to return nullptr, we need to be cautious here: if we are compiling with assertions enabled, *and* have a malloc() (etc) implementation that returns nullptr for alloc(0), we need to skip the assertion check, since we know the result won't be used.

Note: a similar check will be inserted in the xtensa branch separately.
Note 2: LLVM backend already has this check via Codegen_Posix.cpp
  • Loading branch information
steven-johnson committed Dec 28, 2022
1 parent ade8b56 commit 69491d9
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/CodeGen_C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3232,7 +3232,20 @@ void CodeGen_C::visit(const Allocate *op) {
}

if (!on_stack) {
create_assertion(op_name, Call::make(Int(32), "halide_error_out_of_memory", {}, Call::Extern));
ostringstream check;
if (is_const_zero(op->condition)) {
// Assertion always succeeds here, since allocation is never used
check << print_expr(const_true());
} else {
// Assert that the allocation worked....
check << "((" << op_name << " != nullptr) || (" << size_id << " == 0))";
if (!is_const_one(op->condition)) {
// ...but if the condition is false, it's OK for the new_expr to be null.
string op_condition = print_assignment(Bool(), print_expr(op->condition));
check << " || (!" << op_condition << ")";
}
}
create_assertion(check.str(), Call::make(Int(32), "halide_error_out_of_memory", {}, Call::Extern));

stream << get_indent();
string free_function = op->free_function.empty() ? "halide_free" : op->free_function;
Expand Down

0 comments on commit 69491d9

Please sign in to comment.