Return enum constant values as their int64_t bit pattern - #1096
Conversation
GetEnumConstantValue returns size_t and calls APSInt::getExtValue unguarded, which asserts above INT64_MAX. Round-tripping large values through std::stoul (compiler-research#970) throws where unsigned long is 32 bit (LLP64 Windows, wasm32), and a size_t return truncates there regardless. ROOT's Windows CI hit this as an uncaught out_of_range in MetaClingTests test_GH_20925. Return the 64-bit pattern as int64_t everywhere: getExtValue when representable, the zero-extended value as two's complement otherwise.
c385166 to
14f494b
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1096 +/- ##
=======================================
Coverage 87.68% 87.68%
=======================================
Files 23 23
Lines 6382 6384 +2
=======================================
+ Hits 5596 5598 +2
Misses 786 786
🚀 New features to boost your workflow:
|
|
|
||
| auto HugeConstants = Cpp::GetEnumConstants(Decls[1]); | ||
| EXPECT_EQ(Cpp::GetEnumConstantValue(HugeConstants[0]), | ||
| (int64_t)((uint64_t)1 << 63)); |
There was a problem hiding this comment.
warning: no header providing "int64_t" is directly included [misc-include-cleaner]
unittests/CppInterOp/EnumReflectionTest.cpp:7:
+ #include <cstdint>|
|
||
| auto HugeConstants = Cpp::GetEnumConstants(Decls[1]); | ||
| EXPECT_EQ(Cpp::GetEnumConstantValue(HugeConstants[0]), | ||
| (int64_t)((uint64_t)1 << 63)); |
There was a problem hiding this comment.
warning: no header providing "uint64_t" is directly included [misc-include-cleaner]
(int64_t)((uint64_t)1 << 63));
^| } | ||
|
|
||
| size_t GetEnumConstantValue(ConstDeclRef DRef) { | ||
| int64_t GetEnumConstantValue(ConstDeclRef DRef) { |
There was a problem hiding this comment.
Is that a platform-independent typedef?
There was a problem hiding this comment.
Yes, int64_t is available on all platforms from <cstdint>. We already have API's using typedefs from cstdint: GetBaseClassOffset returns int64_t, and InsertOrReplaceJitSymbol accepts uint64_t param, which matches APSInt::getExtValue()
Supersedes #970, from the ROOT migration commit root-project/root@4ccb37c with fixes for the Windows and WASM failures where 32-bit unsigned long overflows stoul. The fallback in that PR parsed 1ULL<<63 with std::stoul which throew out_of_range (unsigned long is 32-bit on those platforms)
GetEnumConstantValue returns
size_tand callsAPSInt::getExtValueunguarded, which asserts aboveINT64_MAX. Round-tripping large values through std::stoul throws where unsigned long is 32 bit (LLP64 Windows, wasm32), and a size_t return truncates there regardless. ROOT's Windows CI hit this as an uncaught out_of_range in MetaClingTeststest_GH_20925.