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 &lt;&lt; 128`. This triggered 
an assertion in `APInt::operator&lt;&lt;=` 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

Reply via email to