Skip to content

Fix: GetEnumConstantValue when value can't be within int64_t - #970

Open
Vipul-Cariappa wants to merge 1 commit into
compiler-research:mainfrom
Vipul-Cariappa:dev/GetEnumConstantValue
Open

Fix: GetEnumConstantValue when value can't be within int64_t#970
Vipul-Cariappa wants to merge 1 commit into
compiler-research:mainfrom
Vipul-Cariappa:dev/GetEnumConstantValue

Conversation

@Vipul-Cariappa

Copy link
Copy Markdown
Collaborator

No description provided.

return INTEROP_RETURN(Val.getExtValue());
llvm::SmallString<40> StrVal;
Val.toString(StrVal);
return INTEROP_RETURN(std::stoul(StrVal.c_str()));

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need macro to check if sizeof(unsigned long) == sizeof(size_t) then call stoul, else if sizeof(unsigned long long) == sizeof(size_t), call stoull? For all the systems we are interested (64 bit), I believe sizeof(unsigned long) == sizeof(unsigned long long) == 64. Then we will also have to change the return type. What is the enum value is negative...!?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codecov

codecov Bot commented May 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.64%. Comparing base (070b0a4) to head (ebde8a0).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #970   +/-   ##
=======================================
  Coverage   87.63%   87.64%           
=======================================
  Files          23       23           
  Lines        6364     6368    +4     
=======================================
+ Hits         5577     5581    +4     
  Misses        787      787           
Files with missing lines Coverage Δ
lib/CppInterOp/CppInterOp.cpp 90.44% <100.00%> (+0.01%) ⬆️
Files with missing lines Coverage Δ
lib/CppInterOp/CppInterOp.cpp 90.44% <100.00%> (+0.01%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vgvassilev vgvassilev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@aaronj0

aaronj0 commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Hi, just wanted to see if this can be rebased and landed.

@aaronj0
aaronj0 force-pushed the dev/GetEnumConstantValue branch from bd7dde6 to ebde8a0 Compare August 26, 2026 14:26
@github-actions

Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

aaronj0 added a commit to aaronj0/CppInterOp that referenced this pull request Aug 27, 2026
GetEnumConstantValue returns size_t and calls APSInt::getExtValue
unguarded, which asserts for enumerators above INT64_MAX ("Too many
bits for int64_t") and truncates 64-bit values wherever size_t is
32 bit (win32, wasm32). Round-tripping the large values through a
string and std::stoul (the compiler-research#970 approach) throws std::out_of_range
wherever unsigned long is 32 bit — LLP64 Windows and ILP32 — which is
what fails compiler-research#970's msvc and emscripten lanes, and was seen in ROOT's
Windows CI as an uncaught std::_Xout_of_range from
Cpp::GetEnumConstantValue taking the interpreter process down
(MetaClingTests test_GH_20925, enum value 1 << 63).

Return the 64-bit bit pattern as int64_t on all platforms instead:
getExtValue when the value is representable, the zero-extended pattern
as two's complement otherwise. No string round-trip, no throw, and the
width no longer depends on the platform's size_t.
aaronj0 added a commit to aaronj0/CppInterOp that referenced this pull request Aug 27, 2026
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.
aaronj0 added a commit to aaronj0/CppInterOp that referenced this pull request Aug 27, 2026
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.
aaronj0 added a commit to aaronj0/CppInterOp that referenced this pull request Aug 27, 2026
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants