[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