[clang] [clang] Implement C2y stdc_load8_* endian-aware 8-bit load functions (PR #203666)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Sun Sep 6 00:01:19 PDT 2026


================
@@ -2103,6 +2103,91 @@ static bool isOneByteCharacterType(QualType T) {
   return T->isCharType() || T->isChar8Type();
 }
 
+static bool interp__builtin_load8(InterpState &S, CodePtr OpPC,
+                                  const InterpFrame *Frame,
+                                  const CallExpr *Call, bool IsBigEndian,
+                                  bool IsAligned) {
+  Pointer Ptr = S.Stk.pop<Pointer>();
+
+  if (Ptr.isZero()) {
+    S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_null)
+        << AK_Read;
+    return false;
+  }
+
+  if (!isReadable(Ptr) && !Ptr.isOnePastEnd())
+    return false;
+
+  if (IsAligned) {
+    CharUnits RequiredAlign =
+        S.getASTContext().getTypeAlignInChars(Call->getType());
+    APValue AV = Ptr.toAPValue(S.getASTContext());
+    CharUnits BaseAlignment =
+        GetBaseAlignment(S.getASTContext(), AV.getLValueBase());
+    CharUnits PtrAlign = BaseAlignment.alignmentAtOffset(AV.getLValueOffset());
+    if (PtrAlign < RequiredAlign) {
+      S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_load8_unaligned)
+          << S.getASTContext().BuiltinInfo.getQuotedName(
+                 Call->getBuiltinCallee())
+          << RequiredAlign.getQuantity() << PtrAlign.getQuantity();
+      return false;
+    }
+  }
+
+  // A string pointer has no Descriptor; treat it as an array of its
+  // character type.
+  bool IsArray;
+  QualType ElemTy;
+  if (Ptr.isStringPointer()) {
+    IsArray = true;
+    ElemTy = getElemType(Ptr);
+  } else {
+    const Descriptor *Desc = Ptr.getFieldDesc();
+    IsArray = Desc->isArray();
+    ElemTy = IsArray ? Desc->getElemQualType() : Desc->getType();
+  }
+
+  if (IsArray)
+    Ptr = Ptr.expand();
+
+  uint64_t BaseIdx = Ptr.getIndex();
+  uint64_t ArraySize = Ptr.getNumElems();
+  uint64_t RemainingElems = ArraySize - BaseIdx;
+
+  unsigned ByteWidth = S.getASTContext().getTypeSize(Call->getType()) / 8;
+  if (ByteWidth > RemainingElems) {
+    uint64_t LastIndex = llvm::SaturatingAdd(BaseIdx, uint64_t(ByteWidth - 1));
+    if (IsArray)
+      S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_array_index)
+          << LastIndex << /*array*/ 0 << ArraySize;
+    else
+      S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_array_index)
+          << LastIndex << /*non-array*/ 1;
----------------
tbaederr wrote:

IIRC you can just pass `ArraySize` in both cases and you won't need the if.

https://github.com/llvm/llvm-project/pull/203666


More information about the cfe-commits mailing list