godot-cpp icon indicating copy to clipboard operation
godot-cpp copied to clipboard

Passing nullptr to functions with nullable parameter (`*parent = nullptr`) crashes

Open saki7 opened this issue 3 years ago • 1 comments

For this kind of interface:

TreeItem *create_item(TreeItem *parent = nullptr, int32_t idx = -1);

Current binding_generator.py generates implementation like below:

TreeItem *Tree::create_item(TreeItem *parent, int32_t idx) {
    /* ... snip ... */
    return internal::_call_native_mb_ret_obj<TreeItem>(___method_bind, _owner, parent->_owner, &idx_encoded);
}

When you actually call this function with the default argument, it crashes at parent->_owner because parent is nullptr. If I change parent->_owner to parent ? parent->_owner : nullptr, then it is working.

I noticed this bug when I was using TreeItem, but I think this issue also affects other classes with similar interfaces too. I assume the script should generate different code for nullable parameters.

EDIT: Theoretically, there might be some other cases where the function has a nullable pointer parameter without default value, but I'm not sure how many of godot-cpp's API matches that form.

Relevant location: https://github.com/godotengine/godot-cpp/blob/bffedfed1eb297b697fa4d139ac9d03b5c9fabd6/binding_generator.py#L1499-L1501

saki7 avatar Jul 11 '22 21:07 saki7

Have bindings generate obj ? obj->_owner : nullptr is the safest solution I can think of, can't avoid the duality wrapper/real object. The only way to allow asserting in debug build (for example) would require the Godot API to tell wether or not an argument is nullable (but they often are). Might need a look at APIs with Ref<T> arguments as well, to see if they handle it? (there are a lot more)

Zylann avatar Jul 13 '22 00:07 Zylann