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
…) (#7256)

* Conditional allocations shouldn't fail for size=0 in C++ backend (#7255)

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

* Update CodeGen_C.cpp
  • Loading branch information
steven-johnson authored Dec 28, 2022
1 parent ade8b56 commit 04bb986
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions 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 Expand Up @@ -3414,7 +3427,7 @@ int test1(struct halide_buffer_t *_buf_buffer, float _alpha, int32_t _beta, void
} // overflow test tmp.heap
int64_t _3 = _2;
int32_t *_tmp_heap = (int32_t *)halide_malloc(_ucon, sizeof(int32_t )*_3);
if (!_tmp_heap)
if (!((_tmp_heap != nullptr) || (_3 == 0)))
{
int32_t _4 = halide_error_out_of_memory(_ucon);
return _4;
Expand Down

0 comments on commit 04bb986

Please sign in to comment.