llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: None (srimanreddy4) <details> <summary>Changes</summary> This PR fixes a crash (assertion failure) in `EnumDecl::getValueRange` when calculating the range of an enum that uses `__int128` types and covers the full 128-bit width. **The Bug:** When `NumPositiveBits` equals the integer width (e.g., 128 for `__int128`), the code previously attempted to calculate `Max = 1 << 128`. This triggered an assertion in `APInt::operator<<=` because the shift amount must be strictly less than the bit width. **The Fix:** Added a check to verify if `NumPositiveBits` is greater than or equal to `Bitwidth`. If so, `Max` is set to 0 (representing the wrapped value) to avoid the invalid shift operation. **Tests:** Added a regression test in `clang/test/SemaCXX/pr173182.cpp` which reproduces the crash using the code snippet from the issue. Fixes #<!-- -->173182. --- Full diff: https://github.com/llvm/llvm-project/pull/173213.diff 2 Files Affected: - (modified) clang/lib/AST/Decl.cpp (+5-2) - (added) clang/test/SemaCXX/pr173182.cpp (+10) ``````````diff diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index b12f042646bbb..82cec455895a3 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -5129,8 +5129,11 @@ void EnumDecl::getValueRange(llvm::APInt &Max, llvm::APInt &Min) const { unsigned NumBits = std::max(NumNegativeBits, NumPositiveBits + 1); Max = llvm::APInt(Bitwidth, 1) << (NumBits - 1); Min = -Max; - } else { - Max = llvm::APInt(Bitwidth, 1) << NumPositiveBits; + } else { + if (NumPositiveBits >= Bitwidth) + Max = llvm::APInt::getZero(Bitwidth); + else + Max = llvm::APInt(Bitwidth, 1) << NumPositiveBits; Min = llvm::APInt::getZero(Bitwidth); } } diff --git a/clang/test/SemaCXX/pr173182.cpp b/clang/test/SemaCXX/pr173182.cpp new file mode 100644 index 0000000000000..7469080e17c4d --- /dev/null +++ b/clang/test/SemaCXX/pr173182.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-unknown-linux-gnu %s + +enum E { // expected-warning {{enumeration values exceed range of largest integer}} + V1 = (__int128)0x1000000000000000, + V2 = (V1 << 64) + 1 +}; + +__int128 get_val() { + return (enum E)__int128(V2 >> 4); +} \ No newline at end of file `````````` </details> https://github.com/llvm/llvm-project/pull/173213 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
