[clang] 7f0bbbb - [clang][Interp] Change array index types in OffsetHelper

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Sat Apr 20 10:31:52 PDT 2024


Author: Timm Bäder
Date: 2024-04-20T19:31:41+02:00
New Revision: 7f0bbbb19b4f13c2efb400db300817aa7ed589cc

URL: https://github.com/llvm/llvm-project/commit/7f0bbbb19b4f13c2efb400db300817aa7ed589cc
DIFF: https://github.com/llvm/llvm-project/commit/7f0bbbb19b4f13c2efb400db300817aa7ed589cc.diff

LOG: [clang][Interp] Change array index types in OffsetHelper

This is closer to that the current interpreter does. It also fixes
diagnostics in a case I was looking into. Unfortunately, this is not
possible to test right now since it requires a large array and we
don't implement array fillers yet.

Added: 
    

Modified: 
    clang/lib/AST/Interp/Interp.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index dd0bacd73acb10..cebedf59e0593f 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1548,17 +1548,16 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
   if (!CheckArray(S, OpPC, Ptr))
     return false;
 
-  // Get a version of the index comparable to the type.
-  T Index = T::from(Ptr.getIndex(), Offset.bitWidth());
-  // Compute the largest index into the array.
-  T MaxIndex = T::from(Ptr.getNumElems(), Offset.bitWidth());
+  uint64_t Index = Ptr.getIndex();
+  uint64_t MaxIndex = static_cast<uint64_t>(Ptr.getNumElems());
 
   bool Invalid = false;
   // Helper to report an invalid offset, computed as APSInt.
   auto DiagInvalidOffset = [&]() -> void {
     const unsigned Bits = Offset.bitWidth();
-    APSInt APOffset(Offset.toAPSInt().extend(Bits + 2), false);
-    APSInt APIndex(Index.toAPSInt().extend(Bits + 2), false);
+    APSInt APOffset(Offset.toAPSInt().extend(Bits + 2), /*IsUnsigend=*/false);
+    APSInt APIndex(APInt(Bits + 2, Index, /*IsSigned=*/true),
+                   /*IsUnsigned=*/false);
     APSInt NewIndex =
         (Op == ArithOp::Add) ? (APIndex + APOffset) : (APIndex - APOffset);
     S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_array_index)
@@ -1569,22 +1568,24 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
   };
 
   if (Ptr.isBlockPointer()) {
-    T MaxOffset = T::from(MaxIndex - Index, Offset.bitWidth());
+    uint64_t IOffset = static_cast<uint64_t>(Offset);
+    uint64_t MaxOffset = MaxIndex - Index;
+
     if constexpr (Op == ArithOp::Add) {
       // If the new offset would be negative, bail out.
-      if (Offset.isNegative() && (Offset.isMin() || -Offset > Index))
+      if (Offset.isNegative() && (Offset.isMin() || -IOffset > Index))
         DiagInvalidOffset();
 
       // If the new offset would be out of bounds, bail out.
-      if (Offset.isPositive() && Offset > MaxOffset)
+      if (Offset.isPositive() && IOffset > MaxOffset)
         DiagInvalidOffset();
     } else {
       // If the new offset would be negative, bail out.
-      if (Offset.isPositive() && Index < Offset)
+      if (Offset.isPositive() && Index < IOffset)
         DiagInvalidOffset();
 
       // If the new offset would be out of bounds, bail out.
-      if (Offset.isNegative() && (Offset.isMin() || -Offset > MaxOffset))
+      if (Offset.isNegative() && (Offset.isMin() || -IOffset > MaxOffset))
         DiagInvalidOffset();
     }
   }
@@ -1601,7 +1602,7 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
   else
     Result = WideIndex - WideOffset;
 
-  S.Stk.push<Pointer>(Ptr.atIndex(static_cast<unsigned>(Result)));
+  S.Stk.push<Pointer>(Ptr.atIndex(static_cast<uint64_t>(Result)));
   return true;
 }
 


        


More information about the cfe-commits mailing list