[C++] : Issue with generated code when naked buffer on a field
Opened this issue · 0 comments
nolankramer commented
This issue includes the issue pointed to by #8144, but was never actually fixed upstream due to developer inactivity.
As such, I'm riving their issue, and expanding on it - I found another place where it was assumed the user would never use naked pointers in the object API.
Here was their original example:
static_assert( FLATBUFFERS_VERSION_MAJOR == 23 &&
FLATBUFFERS_VERSION_MINOR == 5 &&
FLATBUFFERS_VERSION_REVISION == 26,
"Non-compatible flatbuffers version included" );
Given this simplified schema:
table A{
field1: uint32;
}
table B {
list : [A] (required, cpp_ptr_type:"naked");
}
root_type B;
The erronous code is produced here:
inline void B::UnPackTo ( BT *_o, const ::flatbuffers::resolver_function_t *_resolver ) const {
(void)_o;
(void)_resolver;
{
auto _e = list();
if ( _e ){
_o->list.resize( _e->size() );
for ( ::flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++ ){
if ( _o->list[_i] ){
_e->Get( _i )->UnPackTo( _o->list[_i].get(), _resolver ); //here is the error : the .get()
}
else {
_o->list[_i] = ( _e->Get( _i )->UnPack( _resolver ) );
}
;
}
}
else {
_o->list.resize( 0 );
}
}
}
Additionally, defining just a field with a naked_ptr attribute on a circular table type can also result in erronous code:
table A{
field1: B (cpp_ptr_type:"naked");
field2: B (cpp_ptr_type:"naked");
}
table B {
blah: uint;
}
root_type B;
inline void A::UnPackTo(AT*_o, const ::flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = field1(); if (_e) { if(_o->field1) { _e->UnPackTo(_o->field1.get(), _resolver); } else { _o->field1 = (_e->UnPack(_resolver)); } } else if (_o->field1) { _o->field1.reset(); } } // Notice that .get() and .reset() are called
{ auto _e = field2(); if (_e) { if(_o->field2) { _e->UnPackTo(_o->field2.get(), _resolver); } else { _o->field2 = (_e->UnPack(_resolver)); } } else if (_o->field2) { _o->field2.reset(); } } // Notice that .get() and .reset() are called
}
In order to address this, I'm issuing a new PR that I will carry all the way through. The PR will include the fix from the included issue, as well as the fix for the second example.