-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Fix issues with uint64 enums #5265
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, this is a ton of cleanup, making the code generators more maintainable, and new tests too, thanks!
My comments are minor, and the CI failure is a flake, so I think we can merge as is.. you think it is ready?
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; | ||
|
||
bool Deserialize(const Parser &parser, const reflection::EnumVal *val); | ||
|
||
uint64_t GetAsUInt64() const { return static_cast<uint64_t>(value); } | ||
int64_t GetAsInt64() const { return value; } | ||
bool IsZero() const { return 0 == value; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two methods are nicely descriptive, but a bit superfluous, as using an int as a bool is fine in C++
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IsZero and IsNotZero were added for visibility during refactoring.
The 'value` became private and I left these methods.
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; | ||
|
||
bool Deserialize(const Parser &parser, const reflection::EnumVal *val); | ||
|
||
uint64_t GetAsUInt64() const { return static_cast<uint64_t>(value); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I appreciate that this refactor is cleaner, we also have to think about backwards compatibility, since this class is a public API. In that way, I'd prefer for value to keep existing for the signed case, and there to be a method to get the unsigned one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it is no big deal for people that access value
to replace it with your new method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EnumVal and EnumDef are internal
public. They are not used outside in the external (generated) code.
Until Monday, I will add new tests to cover the changes. If all will pass we can try merge to master. |
Ok, let me know. |
@aardappel I propose to limit the enums with
The binary value of
This is unexpected, even with experience in C++. |
Yes, likely constraining |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow this is a crazy amount of changes, hard for me to review what impact this has. But I can also see it would have been hard to split up. I think we're just going to have to merge it and see the impact.
I was thinking of doing a 1.11 release very soon. It may be wise to merge this right after, to reduce risk. On the other hand, merging it before has the advantage that the improvements will get to more people. WDYT?
Better will be after 1.11.
|
What was the memory leak? What was leaking? And yes, sounds like our test does not conform to Protobuf. Not sure if that is a problem, if FlatBuffers is more lenient than Protobuf we don't necessarily care to enforce ProtoBuf rules. In fact, most of the |
And yes, I will get started with the 1.11 release process right then. |
GCC8.2, GCC7.3, Clang 7.0, MSVC2017 - detect leakage if proto-enum has aliased values.
If I right, the problem is located here: flatbuffers/src/idl_parser.cpp Lines 2033 to 2042 in 23bb574
There are two issues:
The current PR fix both issues. |
42df4d4
to
7fa3327
Compare
Ok, but we said we weren't going to merge this one until after 1.11, so do you want to make a small PR that just fixes the leak (& invalid pointers) ? |
Ok, I'll prepare the patch. |
530a63c
to
061da18
Compare
- update the bit_flags enum monster_test::Color to unsigned type - declare the explicit size of generated enum names
Ok, 1.11 landed, so this can now go in. Can you rebase? |
0aab2d3
to
513e0bd
Compare
- hide the implementation of enums from code generators - fix uint64 the issue in the cpp-generator - fix google#5108 - new tests - enums with bit_flags attribute should be unsigned
513e0bd
to
89c6eee
Compare
@aardappel |
FLATBUFFERS_CHECKED_ERROR AssignEnumeratorValue(const std::string &value) { | ||
user_value = true; | ||
auto ascending = false; | ||
if (enum_def.IsUInt64()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a lot of code in this file that goes along this pattern of if (enum_def.IsUInt64())
followed by two very similar bits of code. I guess you evaluated that it wasn't worth templatizing?
Also, not necessarily for this PR, but worth a thought for the future: maybe we should start splitting up idl_parser.cpp
into multiple files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about IsUInt64()
generalization. Probably, this is impossible by design.
The IsUInt64() can't be used for a template specialization at compile time.
The EnumDef is the switch-based strategy to get access to enum values. This strategy emulates a virtual table for methods like ToString.
I have made IsUInt64()
private to isolate from a high-level code.
It is possible to apply classical inheritance if it is needed.
About splitting idp_parser.cpp
I thought too.
In time, a solution will be found.
- move EnumDef::ReverseLookup implementation to idl_parser.cpp - fix typos
Ready for landing if two latest commits are ok. |
Yes, looks good.. thanks for your hard work, again :) |
Refactoring of EnumDef and EnumVal classes (#5161)
The main idea: disable direct access to an enum value.
All available tests passed.
New tests will be added to this PR before landing to cover most of the changes.