Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[C++] : Issue with generated code when naked buffer on a field #8403

Open
nolankramer opened this issue Sep 25, 2024 · 0 comments · May be fixed by #8404
Open

[C++] : Issue with generated code when naked buffer on a field #8403

nolankramer opened this issue Sep 25, 2024 · 0 comments · May be fixed by #8404

Comments

@nolankramer
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant