8#include "../ExprConstShared.h"
20#include "llvm/Support/SipHash.h"
28 for (
const Expr *
E :
C->arguments()) {
37 assert(
Frame->getFunction()->getNumParams() > Index);
38 unsigned Offset =
Frame->getFunction()->getParamOffset(Index);
39 return Frame->getParam<
T>(Offset);
44 unsigned Offset =
Frame->getFunction()->getParamOffset(Index);
46 R =
Frame->getParam<
T>(Offset).toAPSInt());
56 else if (IntWidth == 16)
58 llvm_unreachable(
"Int isn't 16 or 32 bit?");
67 else if (LongWidth == 32)
69 else if (LongWidth == 16)
71 llvm_unreachable(
"long isn't 16, 32 or 64 bit?");
89 std::optional<PrimType>
T = S.getContext().classify(QT);
94 int64_t
V = Val.getSExtValue();
98 uint64_t
V = Val.getZExtValue();
105 if constexpr (std::is_same_v<T, APInt>)
107 else if constexpr (std::is_same_v<T, APSInt>)
112 std::is_signed_v<T>),
113 !std::is_signed_v<T>),
119 ValueT, { Dest.
deref<
T>() = T::from(
static_cast<T>(
Value)); });
123 std::optional<PrimType> &
T) {
129 return Ret<X>(S, OpPC);
146 llvm_unreachable(
"Unsupported return type for builtin function");
153 auto Loc = S.Current->getSource(OpPC);
155 S.CCEDiag(
Loc, diag::note_constexpr_invalid_function)
159 S.CCEDiag(
Loc, diag::note_invalid_subexpr_in_const_expr);
165 unsigned Depth = S.Current->getDepth();
167 return F && F->isInStdNamespace() && F->getIdentifier() &&
168 F->getIdentifier()->isStr(
"is_constant_evaluated");
173 if (S.inConstantContext() && !S.checkingPotentialConstantExpression() &&
174 S.getEvalStatus().
Diag &&
175 (Depth == 1 || (Depth == 2 && isStdCall(Caller->
getCallee())))) {
179 diag::warn_is_constant_evaluated_always_true_constexpr)
184 diag::warn_is_constant_evaluated_always_true_constexpr)
196 unsigned ID =
Func->getBuiltinID();
200 if (ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp)
203 uint64_t Limit = ~static_cast<uint64_t>(0);
204 if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp)
226 for (;; ++IndexA, ++IndexB, ++Steps) {
236 uint8_t CA = PA.
deref<uint8_t>();
237 uint8_t CB = PB.
deref<uint8_t>();
242 }
else if (CA < CB) {
246 if (CA == 0 || CB == 0)
257 unsigned ID =
Func->getBuiltinID();
260 if (ID == Builtin::BIstrlen || ID == Builtin::BIwcslen)
275 if (ID == Builtin::BI__builtin_wcslen || ID == Builtin::BIwcslen) {
277 assert(ElemSize == AC.getTypeSizeInChars(AC.getWCharType()).getQuantity());
281 for (
size_t I = StrPtr.
getIndex();; ++I, ++Len) {
290 Val = ElemPtr.
deref<uint8_t>();
293 Val = ElemPtr.
deref<uint16_t>();
296 Val = ElemPtr.
deref<uint32_t>();
299 llvm_unreachable(
"Unsupported char size");
324 for (
unsigned I = 0;; ++I) {
330 if (Elem.
deref<int8_t>() == 0)
333 Str += Elem.
deref<
char>();
338 Fill = llvm::APInt(32, 0);
339 else if (StringRef(Str).getAsInteger(0, Fill))
342 const llvm::fltSemantics &TargetSemantics =
349 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
352 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
361 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
364 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
373 const llvm::fltSemantics &TargetSemantics =
407 else if (LHS.
isNan() || RHS < LHS)
431 else if (LHS.
isNan() || RHS > LHS)
467 bool IsInf = Arg.
isInf();
534 case Builtin::BI__builtin_isgreater:
536 case Builtin::BI__builtin_isgreaterequal:
538 case Builtin::BI__builtin_isless:
540 case Builtin::BI__builtin_islessequal:
542 case Builtin::BI__builtin_islessgreater: {
547 case Builtin::BI__builtin_isunordered:
550 llvm_unreachable(
"Unexpected builtin ID: Should be a floating point "
551 "comparison function");
564 PrimType FPClassArgT = *S.getContext().classify(
Call->getArg(1)->getType());
570 static_cast<int32_t
>((F.
classify() & FPClassArg).getZExtValue());
588 case APFloat::fcInfinity:
591 case APFloat::fcNormal:
594 case APFloat::fcZero:
627 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
630 APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
false))
632 if (Val.isNegative())
642 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
651 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
660 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
662 pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(),
Call->getType());
670 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
681 assert(
Call->getNumArgs() == 1);
686 int32_t ReturnVal =
static_cast<int32_t
>(ResultClass);
698 unsigned NumArgs =
Call->getNumArgs();
699 assert(NumArgs == 2 || NumArgs == 3);
701 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
716 PrimType AmountT = *S.getContext().classify(
Call->getArg(1)->getType());
717 PrimType ValueT = *S.getContext().classify(
Call->getArg(0)->getType());
738 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
741 uint64_t N =
Value.countr_zero();
750 assert(
Call->getArg(0)->isLValue());
756 }
else if (PtrT ==
PT_Ptr) {
760 assert(
false &&
"Unsupported pointer type passed to __builtin_addressof()");
771 TYPE_SWITCH(ArgT,
const T &Arg = S.Stk.peek<
T>(); S.Stk.push<
T>(Arg););
773 return Func->getDecl()->isConstexpr();
780 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
806 unsigned BuiltinOp =
Func->getBuiltinID();
807 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
808 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
814 QualType ResultType =
Call->getArg(2)->getType()->getPointeeType();
815 PrimType ResultT = *S.getContext().classify(ResultType);
819 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
820 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
821 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
822 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
824 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
826 uint64_t LHSSize = LHS.getBitWidth();
827 uint64_t RHSSize = RHS.getBitWidth();
829 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
835 if (IsSigned && !AllSigned)
838 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
839 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
846 llvm_unreachable(
"Invalid value for BuiltinOp");
847 case Builtin::BI__builtin_add_overflow:
848 case Builtin::BI__builtin_sadd_overflow:
849 case Builtin::BI__builtin_saddl_overflow:
850 case Builtin::BI__builtin_saddll_overflow:
851 case Builtin::BI__builtin_uadd_overflow:
852 case Builtin::BI__builtin_uaddl_overflow:
853 case Builtin::BI__builtin_uaddll_overflow:
854 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, Overflow)
855 : LHS.uadd_ov(RHS, Overflow);
857 case Builtin::BI__builtin_sub_overflow:
858 case Builtin::BI__builtin_ssub_overflow:
859 case Builtin::BI__builtin_ssubl_overflow:
860 case Builtin::BI__builtin_ssubll_overflow:
861 case Builtin::BI__builtin_usub_overflow:
862 case Builtin::BI__builtin_usubl_overflow:
863 case Builtin::BI__builtin_usubll_overflow:
864 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, Overflow)
865 : LHS.usub_ov(RHS, Overflow);
867 case Builtin::BI__builtin_mul_overflow:
868 case Builtin::BI__builtin_smul_overflow:
869 case Builtin::BI__builtin_smull_overflow:
870 case Builtin::BI__builtin_smulll_overflow:
871 case Builtin::BI__builtin_umul_overflow:
872 case Builtin::BI__builtin_umull_overflow:
873 case Builtin::BI__builtin_umulll_overflow:
874 Result = LHS.isSigned() ? LHS.smul_ov(RHS, Overflow)
875 : LHS.umul_ov(RHS, Overflow);
881 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
882 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
883 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
891 if (!APSInt::isSameValue(Temp,
Result))
899 assert(
Func->getDecl()->getReturnType()->isBooleanType());
909 unsigned BuiltinOp =
Func->getBuiltinID();
910 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
911 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
912 PrimType CarryT = *S.getContext().classify(
Call->getArg(2)->getType());
929 bool FirstOverflowed =
false;
930 bool SecondOverflowed =
false;
933 llvm_unreachable(
"Invalid value for BuiltinOp");
934 case Builtin::BI__builtin_addcb:
935 case Builtin::BI__builtin_addcs:
936 case Builtin::BI__builtin_addc:
937 case Builtin::BI__builtin_addcl:
938 case Builtin::BI__builtin_addcll:
940 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
942 case Builtin::BI__builtin_subcb:
943 case Builtin::BI__builtin_subcs:
944 case Builtin::BI__builtin_subc:
945 case Builtin::BI__builtin_subcl:
946 case Builtin::BI__builtin_subcll:
948 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
953 CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed);
956 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
957 PrimType CarryOutT = *S.getContext().classify(CarryOutType);
961 assert(
Call->getType() ==
Call->getArg(0)->getType());
970 unsigned BuiltinOp =
Func->getBuiltinID();
971 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
976 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
977 BuiltinOp != Builtin::BI__lzcnt &&
978 BuiltinOp != Builtin::BI__lzcnt64;
981 if (
Func->getBuiltinID() == Builtin::BI__builtin_clzg &&
982 Call->getNumArgs() == 2) {
984 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
1002 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
1006 if (
Func->getBuiltinID() == Builtin::BI__builtin_ctzg &&
1007 Call->getNumArgs() == 2) {
1009 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
1024 PrimType ReturnT = *S.getContext().classify(
Call->getType());
1025 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
1027 assert(Val.getActiveBits() <= 64);
1030 { S.Stk.push<
T>(T::from(Val.byteSwap().getZExtValue())); });
1041 unsigned BuiltinOp =
Func->getBuiltinID();
1043 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
1044 unsigned SizeValOffset = 0;
1045 if (BuiltinOp != Builtin::BI__c11_atomic_is_lock_free)
1049 auto returnBool = [&S](
bool Value) ->
bool {
1065 if (Size.isPowerOfTwo()) {
1067 unsigned InlineWidthBits =
1073 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
1075 return returnBool(
true);
1078 assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);
1081 return returnBool(
true);
1085 if (
APSInt(
APInt(64, IntVal,
false),
true).isAligned(Size.getAsAlign()))
1086 return returnBool(
true);
1089 const Expr *PtrArg =
Call->getArg(1);
1091 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
1094 if (ICE->getCastKind() == CK_BitCast)
1095 PtrArg = ICE->getSubExpr();
1103 return returnBool(
true);
1109 if (BuiltinOp == Builtin::BI__atomic_always_lock_free)
1110 return returnBool(
false);
1126 Result.atIndex(0).initialize();
1128 Result.atIndex(1).initialize();
1143 unsigned BuiltinOp =
Func->getBuiltinID();
1146 PrimType AlignmentT = *S.Ctx.classify(
Call->getArg(1));
1149 if (Alignment < 0 || !Alignment.isPowerOf2()) {
1150 S.FFDiag(
Call, diag::note_constexpr_invalid_alignment) << Alignment;
1154 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
1155 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
1156 S.FFDiag(
Call, diag::note_constexpr_alignment_too_big)
1157 << MaxValue <<
Call->getArg(0)->getType() << Alignment;
1167 APSInt Align = Alignment.extOrTrunc(Src.getBitWidth());
1168 if (BuiltinOp == Builtin::BI__builtin_align_up) {
1170 APSInt((Src + (Align - 1)) & ~(Align - 1), Src.isUnsigned());
1172 }
else if (BuiltinOp == Builtin::BI__builtin_align_down) {
1173 APSInt AlignedVal =
APSInt(Src & ~(Align - 1), Src.isUnsigned());
1176 assert(*S.Ctx.classify(
Call->getType()) ==
PT_Bool);
1177 S.Stk.push<
Boolean>((Src & (Align - 1)) == 0);
1182 assert(FirstArgT ==
PT_Ptr);
1192 if (BuiltinOp == Builtin::BI__builtin_is_aligned) {
1207 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_compute)
1212 assert(BuiltinOp == Builtin::BI__builtin_align_down ||
1213 BuiltinOp == Builtin::BI__builtin_align_up);
1228 assert(Alignment.getBitWidth() <= 64 &&
1229 "Cannot handle > 64-bit address-space");
1230 uint64_t Alignment64 = Alignment.getZExtValue();
1233 ? llvm::alignDown(PtrOffset, Alignment64)
1234 : llvm::alignTo(PtrOffset, Alignment64));
1241 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;
1250 assert(
Call->getNumArgs() == 2 ||
Call->getNumArgs() == 3);
1253 std::optional<PrimType> PtrT = S.Ctx.classify(
Call->getArg(0));
1259 std::optional<APSInt> ExtraOffset;
1261 if (
Call->getNumArgs() == 2) {
1264 PrimType AlignmentT = *S.Ctx.classify(
Call->getArg(1));
1265 PrimType ExtraOffsetT = *S.Ctx.classify(
Call->getArg(2));
1282 if (BaseAlignment < Align) {
1283 S.CCEDiag(
Call->getArg(0),
1284 diag::note_constexpr_baa_insufficient_alignment)
1294 if (AVOffset.
alignTo(Align) != AVOffset) {
1296 S.CCEDiag(
Call->getArg(0),
1297 diag::note_constexpr_baa_insufficient_alignment)
1300 S.CCEDiag(
Call->getArg(0),
1301 diag::note_constexpr_baa_value_insufficient_alignment)
1314 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1315 !
Call->getArg(1)->getType()->isIntegerType())
1324 unsigned BitWidth = Val.getBitWidth();
1325 uint64_t Shift = Index.extractBitsAsZExtValue(8, 0);
1326 uint64_t Length = Index.extractBitsAsZExtValue(8, 8);
1327 Length = Length > BitWidth ? BitWidth : Length;
1330 if (Length == 0 || Shift >= BitWidth) {
1335 uint64_t
Result = Val.getZExtValue() >> Shift;
1336 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
1346 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1347 !
Call->getArg(1)->getType()->isIntegerType() ||
1358 unsigned BitWidth = Val.getBitWidth();
1359 uint64_t Index = Idx.extractBitsAsZExtValue(8, 0);
1361 if (Index < BitWidth)
1362 Val.clearHighBits(BitWidth - Index);
1374 !
Call->getArg(0)->getType()->isIntegerType())
1378 pushInteger(S, Val.countLeadingZeros(), CallType);
1388 !
Call->getArg(0)->getType()->isIntegerType())
1392 pushInteger(S, Val.countTrailingZeros(), CallType);
1400 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1401 !
Call->getArg(1)->getType()->isIntegerType())
1411 unsigned BitWidth = Val.getBitWidth();
1413 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I) {
1415 Result.setBitVal(I, Val[
P++]);
1425 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1426 !
Call->getArg(1)->getType()->isIntegerType())
1436 unsigned BitWidth = Val.getBitWidth();
1438 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I) {
1440 Result.setBitVal(
P++, Val[I]);
1451 if (
Call->getNumArgs() != 4 || !
Call->getArg(0)->getType()->isIntegerType() ||
1452 !
Call->getArg(1)->getType()->isIntegerType() ||
1453 !
Call->getArg(2)->getType()->isIntegerType())
1456 unsigned BuiltinOp =
Func->getBuiltinID();
1461 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
1462 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
1464 unsigned BitWidth = LHS.getBitWidth();
1465 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
1467 IsAdd ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
1468 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
1472 APSInt(ExResult.extractBits(1, BitWidth),
true);
1475 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
1476 PrimType CarryOutT = *S.getContext().classify(CarryOutType);
1498 const auto &Ptr = S.Stk.peek<
Pointer>();
1499 assert(Ptr.getFieldDesc()->isPrimitiveArray());
1501 StringRef R(&Ptr.deref<
char>(), Ptr.getFieldDesc()->getNumElems() - 1);
1502 uint64_t
Result = getPointerAuthStableSipHash(R);
1518 auto returnInt = [&S,
Call](
bool Value) ->
bool {
1542 auto Res =
C.interpretExpr(Arg, Arg->
isGLValue());
1543 if (Res.isInvalid()) {
1548 if (!Res.isInvalid() && !Res.empty()) {
1549 const APValue &LV = Res.toAPValue();
1552 if (
Base.isNull()) {
1554 return returnInt(
true);
1555 }
else if (
const auto *
E =
Base.dyn_cast<
const Expr *>()) {
1556 if (!isa<StringLiteral>(
E))
1557 return returnInt(
false);
1562 return returnInt(
true);
1565 return returnInt(
false);
1571 return returnInt(
true);
1574 return returnInt(
false);
1590 const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
Func->getDecl());
1594 if (!FnII || !FnII->
isStr(
"allocate"))
1598 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1604 if (CTSD->isInStdNamespace() && ClassII && ClassII->
isStr(
"allocator") &&
1606 ElemType = TAL[0].getAsType();
1613 ? diag::note_constexpr_new_untyped
1614 : diag::note_constexpr_new);
1619 S.FFDiag(
Call, diag::note_constexpr_new_not_complete_object_type)
1626 assert(!ElemSize.
isZero());
1629 APInt NumElems, Remainder;
1631 APInt::udivrem(
Bytes, ElemSizeAP, NumElems, Remainder);
1632 if (Remainder != 0) {
1634 S.FFDiag(
Call, diag::note_constexpr_operator_new_bad_size)
1640 if (NumElems.getActiveBits() >
1645 S.FFDiag(
Loc, diag::note_constexpr_new_too_large)
1646 << NumElems.getZExtValue();
1650 std::optional<PrimType> ElemT = S.getContext().classify(ElemType);
1653 if (NumElems.ule(1)) {
1658 Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),
1665 assert(NumElems.ugt(1));
1668 Allocator.allocate(
Call, *ElemT, NumElems.getZExtValue(),
1677 const Descriptor *Desc = S.P.createDescriptor(
1679 false,
false,
false,
1682 if (NumElems.ule(1)) {
1683 Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),
1691 Allocator.allocate(Desc, NumElems.getZExtValue(), S.Ctx.getEvalID(),
1702 const Expr *Source =
nullptr;
1703 const Block *BlockToDelete =
nullptr;
1709 S.CCEDiag(
Call, diag::note_constexpr_deallocate_null);
1714 BlockToDelete = Ptr.
block();
1716 assert(BlockToDelete);
1720 std::optional<DynamicAllocator::Form> AllocForm =
1721 Allocator.getAllocationForm(Source);
1723 if (!Allocator.deallocate(Source, BlockToDelete, S)) {
1726 S.FFDiag(
Loc, diag::note_constexpr_double_delete);
1751 unsigned ID =
Func->getBuiltinID();
1753 assert(
Call->getType() == ElemType);
1754 PrimType ElemT = *S.getContext().classify(ElemType);
1759 unsigned BitWidth =
Result.bitWidth();
1760 for (
unsigned I = 1; I != NumElems; ++I) {
1761 T Elem = Arg.
atIndex(I).deref<T>();
1764 if (ID == Builtin::BI__builtin_reduce_add) {
1766 unsigned OverflowBits = BitWidth + 1;
1768 (PrevResult.toAPSInt(OverflowBits) +
1769 Elem.toAPSInt(OverflowBits)));
1772 }
else if (ID == Builtin::BI__builtin_reduce_mul) {
1774 unsigned OverflowBits = BitWidth * 2;
1776 (PrevResult.toAPSInt(OverflowBits) *
1777 Elem.toAPSInt(OverflowBits)));
1781 }
else if (ID == Builtin::BI__builtin_reduce_and) {
1783 }
else if (ID == Builtin::BI__builtin_reduce_or) {
1785 }
else if (ID == Builtin::BI__builtin_reduce_xor) {
1788 llvm_unreachable(
"Unhandled vector reduce builtin");
1802 assert(
Call->getNumArgs() == 1);
1803 if (
Call->getArg(0)->getType()->isIntegerType()) {
1804 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
1810 assert(
Call->getArg(0)->getType()->isVectorType());
1819 PrimType ElemT = *S.getContext().classify(ElemType);
1823 for (
unsigned I = 0; I != NumElems; ++I) {
1837 assert(
Call->getNumArgs() == 3);
1838 unsigned ID =
Func->getBuiltinID();
1843 assert(!Size.isSigned() &&
"memcpy and friends take an unsigned size");
1845 if (ID == Builtin::BImemcpy || ID == Builtin::BImemmove)
1848 bool Move = (ID == Builtin::BI__builtin_memmove || ID == Builtin::BImemmove);
1851 if (Size.isZero()) {
1858 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_null)
1859 << Move <<
false << !SrcPtr.
isZero()
1872 if (Size.urem(ElemSize) != 0) {
1873 S.FFDiag(S.Current->getSource(OpPC),
1874 diag::note_constexpr_memcpy_unsupported)
1875 << Move <<
false << 0 << ElemType << Size << ElemSize;
1883 SrcElemType = SrcPtr.
getType();
1886 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_type_pun)
1887 << Move << SrcElemType << ElemType;
1895 unsigned N = Size.getZExtValue();
1897 if ((SrcIndex <= DstIndex && (SrcIndex + N) > DstIndex) ||
1898 (DstIndex <= SrcIndex && (DstIndex + N) > SrcIndex)) {
1899 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_overlap)
1908 assert(Size.getZExtValue() % ElemSize == 0);
1925 assert(
Call->getNumArgs() == 3);
1926 unsigned ID =
Func->getBuiltinID();
1932 if (ID == Builtin::BImemcmp || ID == Builtin::BIbcmp ||
1933 ID == Builtin::BIwmemcmp)
1936 if (Size.isZero()) {
1942 (ID == Builtin::BIwmemcmp || ID == Builtin::BI__builtin_wmemcmp);
1949 S.FFDiag(S.Current->getSource(OpPC),
1950 diag::note_constexpr_memcmp_unsupported)
1979 unsigned ElemSize = 1;
1984 size_t ByteSize = Size.getZExtValue() * ElemSize;
1985 size_t CmpSize = std::min(MinBufferSize, ByteSize);
1987 for (
size_t I = 0; I != CmpSize; I += ElemSize) {
1990 T A = *reinterpret_cast<T *>(BufferA.Data.get() + I);
1991 T B = *reinterpret_cast<T *>(BufferB.Data.get() + I);
1993 pushInteger(S, -1, Call->getType());
2001 std::byte A = BufferA.
Data[I];
2002 std::byte B = BufferB.
Data[I];
2016 if (ByteSize <= CmpSize) {
2025 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_past_end)
2026 <<
AK_Read << S.Current->getRange(OpPC);
2034 std::optional<PrimType> ReturnT = S.getContext().classify(
Call);
2036 switch (BuiltinID) {
2037 case Builtin::BI__builtin_is_constant_evaluated:
2041 case Builtin::BI__builtin_assume:
2042 case Builtin::BI__assume:
2044 case Builtin::BI__builtin_strcmp:
2045 case Builtin::BIstrcmp:
2046 case Builtin::BI__builtin_strncmp:
2047 case Builtin::BIstrncmp:
2051 case Builtin::BI__builtin_strlen:
2052 case Builtin::BIstrlen:
2053 case Builtin::BI__builtin_wcslen:
2054 case Builtin::BIwcslen:
2058 case Builtin::BI__builtin_nan:
2059 case Builtin::BI__builtin_nanf:
2060 case Builtin::BI__builtin_nanl:
2061 case Builtin::BI__builtin_nanf16:
2062 case Builtin::BI__builtin_nanf128:
2066 case Builtin::BI__builtin_nans:
2067 case Builtin::BI__builtin_nansf:
2068 case Builtin::BI__builtin_nansl:
2069 case Builtin::BI__builtin_nansf16:
2070 case Builtin::BI__builtin_nansf128:
2075 case Builtin::BI__builtin_huge_val:
2076 case Builtin::BI__builtin_huge_valf:
2077 case Builtin::BI__builtin_huge_vall:
2078 case Builtin::BI__builtin_huge_valf16:
2079 case Builtin::BI__builtin_huge_valf128:
2080 case Builtin::BI__builtin_inf:
2081 case Builtin::BI__builtin_inff:
2082 case Builtin::BI__builtin_infl:
2083 case Builtin::BI__builtin_inff16:
2084 case Builtin::BI__builtin_inff128:
2088 case Builtin::BI__builtin_copysign:
2089 case Builtin::BI__builtin_copysignf:
2090 case Builtin::BI__builtin_copysignl:
2091 case Builtin::BI__builtin_copysignf128:
2096 case Builtin::BI__builtin_fmin:
2097 case Builtin::BI__builtin_fminf:
2098 case Builtin::BI__builtin_fminl:
2099 case Builtin::BI__builtin_fminf16:
2100 case Builtin::BI__builtin_fminf128:
2105 case Builtin::BI__builtin_fminimum_num:
2106 case Builtin::BI__builtin_fminimum_numf:
2107 case Builtin::BI__builtin_fminimum_numl:
2108 case Builtin::BI__builtin_fminimum_numf16:
2109 case Builtin::BI__builtin_fminimum_numf128:
2114 case Builtin::BI__builtin_fmax:
2115 case Builtin::BI__builtin_fmaxf:
2116 case Builtin::BI__builtin_fmaxl:
2117 case Builtin::BI__builtin_fmaxf16:
2118 case Builtin::BI__builtin_fmaxf128:
2123 case Builtin::BI__builtin_fmaximum_num:
2124 case Builtin::BI__builtin_fmaximum_numf:
2125 case Builtin::BI__builtin_fmaximum_numl:
2126 case Builtin::BI__builtin_fmaximum_numf16:
2127 case Builtin::BI__builtin_fmaximum_numf128:
2132 case Builtin::BI__builtin_isnan:
2136 case Builtin::BI__builtin_issignaling:
2141 case Builtin::BI__builtin_isinf:
2146 case Builtin::BI__builtin_isinf_sign:
2151 case Builtin::BI__builtin_isfinite:
2155 case Builtin::BI__builtin_isnormal:
2159 case Builtin::BI__builtin_issubnormal:
2163 case Builtin::BI__builtin_iszero:
2167 case Builtin::BI__builtin_signbit:
2168 case Builtin::BI__builtin_signbitf:
2169 case Builtin::BI__builtin_signbitl:
2173 case Builtin::BI__builtin_isgreater:
2174 case Builtin::BI__builtin_isgreaterequal:
2175 case Builtin::BI__builtin_isless:
2176 case Builtin::BI__builtin_islessequal:
2177 case Builtin::BI__builtin_islessgreater:
2178 case Builtin::BI__builtin_isunordered:
2182 case Builtin::BI__builtin_isfpclass:
2186 case Builtin::BI__builtin_fpclassify:
2191 case Builtin::BI__builtin_fabs:
2192 case Builtin::BI__builtin_fabsf:
2193 case Builtin::BI__builtin_fabsl:
2194 case Builtin::BI__builtin_fabsf128:
2199 case Builtin::BI__builtin_abs:
2200 case Builtin::BI__builtin_labs:
2201 case Builtin::BI__builtin_llabs:
2206 case Builtin::BI__builtin_popcount:
2207 case Builtin::BI__builtin_popcountl:
2208 case Builtin::BI__builtin_popcountll:
2209 case Builtin::BI__builtin_popcountg:
2210 case Builtin::BI__popcnt16:
2211 case Builtin::BI__popcnt:
2212 case Builtin::BI__popcnt64:
2217 case Builtin::BI__builtin_parity:
2218 case Builtin::BI__builtin_parityl:
2219 case Builtin::BI__builtin_parityll:
2224 case Builtin::BI__builtin_clrsb:
2225 case Builtin::BI__builtin_clrsbl:
2226 case Builtin::BI__builtin_clrsbll:
2231 case Builtin::BI__builtin_bitreverse8:
2232 case Builtin::BI__builtin_bitreverse16:
2233 case Builtin::BI__builtin_bitreverse32:
2234 case Builtin::BI__builtin_bitreverse64:
2239 case Builtin::BI__builtin_classify_type:
2244 case Builtin::BI__builtin_expect:
2245 case Builtin::BI__builtin_expect_with_probability:
2250 case Builtin::BI__builtin_rotateleft8:
2251 case Builtin::BI__builtin_rotateleft16:
2252 case Builtin::BI__builtin_rotateleft32:
2253 case Builtin::BI__builtin_rotateleft64:
2254 case Builtin::BI_rotl8:
2255 case Builtin::BI_rotl16:
2256 case Builtin::BI_rotl:
2257 case Builtin::BI_lrotl:
2258 case Builtin::BI_rotl64:
2263 case Builtin::BI__builtin_rotateright8:
2264 case Builtin::BI__builtin_rotateright16:
2265 case Builtin::BI__builtin_rotateright32:
2266 case Builtin::BI__builtin_rotateright64:
2267 case Builtin::BI_rotr8:
2268 case Builtin::BI_rotr16:
2269 case Builtin::BI_rotr:
2270 case Builtin::BI_lrotr:
2271 case Builtin::BI_rotr64:
2276 case Builtin::BI__builtin_ffs:
2277 case Builtin::BI__builtin_ffsl:
2278 case Builtin::BI__builtin_ffsll:
2282 case Builtin::BIaddressof:
2283 case Builtin::BI__addressof:
2284 case Builtin::BI__builtin_addressof:
2289 case Builtin::BIas_const:
2290 case Builtin::BIforward:
2291 case Builtin::BIforward_like:
2292 case Builtin::BImove:
2293 case Builtin::BImove_if_noexcept:
2298 case Builtin::BI__builtin_eh_return_data_regno:
2303 case Builtin::BI__builtin_launder:
2308 case Builtin::BI__builtin_add_overflow:
2309 case Builtin::BI__builtin_sub_overflow:
2310 case Builtin::BI__builtin_mul_overflow:
2311 case Builtin::BI__builtin_sadd_overflow:
2312 case Builtin::BI__builtin_uadd_overflow:
2313 case Builtin::BI__builtin_uaddl_overflow:
2314 case Builtin::BI__builtin_uaddll_overflow:
2315 case Builtin::BI__builtin_usub_overflow:
2316 case Builtin::BI__builtin_usubl_overflow:
2317 case Builtin::BI__builtin_usubll_overflow:
2318 case Builtin::BI__builtin_umul_overflow:
2319 case Builtin::BI__builtin_umull_overflow:
2320 case Builtin::BI__builtin_umulll_overflow:
2321 case Builtin::BI__builtin_saddl_overflow:
2322 case Builtin::BI__builtin_saddll_overflow:
2323 case Builtin::BI__builtin_ssub_overflow:
2324 case Builtin::BI__builtin_ssubl_overflow:
2325 case Builtin::BI__builtin_ssubll_overflow:
2326 case Builtin::BI__builtin_smul_overflow:
2327 case Builtin::BI__builtin_smull_overflow:
2328 case Builtin::BI__builtin_smulll_overflow:
2333 case Builtin::BI__builtin_addcb:
2334 case Builtin::BI__builtin_addcs:
2335 case Builtin::BI__builtin_addc:
2336 case Builtin::BI__builtin_addcl:
2337 case Builtin::BI__builtin_addcll:
2338 case Builtin::BI__builtin_subcb:
2339 case Builtin::BI__builtin_subcs:
2340 case Builtin::BI__builtin_subc:
2341 case Builtin::BI__builtin_subcl:
2342 case Builtin::BI__builtin_subcll:
2347 case Builtin::BI__builtin_clz:
2348 case Builtin::BI__builtin_clzl:
2349 case Builtin::BI__builtin_clzll:
2350 case Builtin::BI__builtin_clzs:
2351 case Builtin::BI__builtin_clzg:
2352 case Builtin::BI__lzcnt16:
2353 case Builtin::BI__lzcnt:
2354 case Builtin::BI__lzcnt64:
2359 case Builtin::BI__builtin_ctz:
2360 case Builtin::BI__builtin_ctzl:
2361 case Builtin::BI__builtin_ctzll:
2362 case Builtin::BI__builtin_ctzs:
2363 case Builtin::BI__builtin_ctzg:
2368 case Builtin::BI__builtin_bswap16:
2369 case Builtin::BI__builtin_bswap32:
2370 case Builtin::BI__builtin_bswap64:
2375 case Builtin::BI__atomic_always_lock_free:
2376 case Builtin::BI__atomic_is_lock_free:
2377 case Builtin::BI__c11_atomic_is_lock_free:
2382 case Builtin::BI__builtin_complex:
2387 case Builtin::BI__builtin_is_aligned:
2388 case Builtin::BI__builtin_align_up:
2389 case Builtin::BI__builtin_align_down:
2394 case Builtin::BI__builtin_assume_aligned:
2399 case clang::X86::BI__builtin_ia32_bextr_u32:
2400 case clang::X86::BI__builtin_ia32_bextr_u64:
2401 case clang::X86::BI__builtin_ia32_bextri_u32:
2402 case clang::X86::BI__builtin_ia32_bextri_u64:
2407 case clang::X86::BI__builtin_ia32_bzhi_si:
2408 case clang::X86::BI__builtin_ia32_bzhi_di:
2413 case clang::X86::BI__builtin_ia32_lzcnt_u16:
2414 case clang::X86::BI__builtin_ia32_lzcnt_u32:
2415 case clang::X86::BI__builtin_ia32_lzcnt_u64:
2420 case clang::X86::BI__builtin_ia32_tzcnt_u16:
2421 case clang::X86::BI__builtin_ia32_tzcnt_u32:
2422 case clang::X86::BI__builtin_ia32_tzcnt_u64:
2427 case clang::X86::BI__builtin_ia32_pdep_si:
2428 case clang::X86::BI__builtin_ia32_pdep_di:
2433 case clang::X86::BI__builtin_ia32_pext_si:
2434 case clang::X86::BI__builtin_ia32_pext_di:
2439 case clang::X86::BI__builtin_ia32_addcarryx_u32:
2440 case clang::X86::BI__builtin_ia32_addcarryx_u64:
2441 case clang::X86::BI__builtin_ia32_subborrow_u32:
2442 case clang::X86::BI__builtin_ia32_subborrow_u64:
2447 case Builtin::BI__builtin_os_log_format_buffer_size:
2452 case Builtin::BI__builtin_ptrauth_string_discriminator:
2457 case Builtin::BI__builtin_constant_p:
2462 case Builtin::BI__noop:
2466 case Builtin::BI__builtin_operator_new:
2471 case Builtin::BI__builtin_operator_delete:
2476 case Builtin::BI__arithmetic_fence:
2481 case Builtin::BI__builtin_reduce_add:
2482 case Builtin::BI__builtin_reduce_mul:
2483 case Builtin::BI__builtin_reduce_and:
2484 case Builtin::BI__builtin_reduce_or:
2485 case Builtin::BI__builtin_reduce_xor:
2490 case Builtin::BI__builtin_elementwise_popcount:
2495 case Builtin::BI__builtin_memcpy:
2496 case Builtin::BImemcpy:
2497 case Builtin::BI__builtin_memmove:
2498 case Builtin::BImemmove:
2503 case Builtin::BI__builtin_memcmp:
2504 case Builtin::BImemcmp:
2505 case Builtin::BI__builtin_bcmp:
2506 case Builtin::BIbcmp:
2507 case Builtin::BI__builtin_wmemcmp:
2508 case Builtin::BIwmemcmp:
2514 S.FFDiag(S.Current->getLocation(OpPC),
2515 diag::note_invalid_subexpr_in_const_expr)
2516 << S.Current->getRange(OpPC);
2526 int64_t &IntResult) {
2528 unsigned N =
E->getNumComponents();
2531 unsigned ArrayIndex = 0;
2533 for (
unsigned I = 0; I != N; ++I) {
2535 switch (
Node.getKind()) {
2546 assert(FieldIndex < RL.
getFieldCount() &&
"offsetof field in wrong type");
2555 int64_t Index = ArrayIndices[ArrayIndex];
2561 Result += Index * ElementSize;
2580 CurrentType = BaseSpec->
getType();
2590 llvm_unreachable(
"Dependent OffsetOfExpr?");
2594 IntResult =
Result.getQuantity();
2611 FieldPtr.
deref<
T>() = T::from(IntValue.getSExtValue()));
2616static bool copyComposite(InterpState &S, CodePtr OpPC,
const Pointer &Src,
2617 Pointer &Dest,
bool Activate);
2619 Pointer &Dest,
bool Activate =
false) {
2623 auto copyField = [&](
const Record::Field &F,
bool Activate) ->
bool {
2625 if (std::optional<PrimType> FT = S.Ctx.classify(F.Decl->getType())) {
2642 for (
const Record::Field &F : R->
fields()) {
2647 if (!copyField(F,
true))
2651 if (!copyField(F, Activate))
2656 for (
const Record::Base &B : R->
bases()) {
2658 if (!copyRecord(S, OpPC, Src.
atField(B.Offset), DestBase, Activate))
2667 Pointer &Dest,
bool Activate =
false) {
2679 for (
unsigned I = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
2690 return copyRecord(S, OpPC, Src, Dest, Activate);
Defines enum values for all the target-independent builtin functions.
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
#define INT_TYPE_SWITCH_NO_BOOL(Expr, B)
#define INT_TYPE_SWITCH(Expr, B)
#define TYPE_SWITCH(Expr, B)
Enumerates target-specific builtins in their own namespaces within namespace clang.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
CharUnits & getLValueOffset()
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
Builtin::Context & BuiltinInfo
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
QualType getWCharType() const
Return the unique wchar_t type available in C++ (and available as __wchar_t as a Microsoft extension)...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
llvm::StringRef getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
Represents a base class of a C++ class.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
bool isInvalidDecl() const
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
Represents a function declaration or definition.
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Helper class for OffsetOfExpr.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Represents a struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Exposes information about the current target.
unsigned getMaxAtomicInlineWidth() const
Return the maximum width lock-free atomic operation which can be inlined given the supported features...
unsigned getIntWidth() const
getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for this target,...
virtual int getEHDataRegisterNumber(unsigned RegNo) const
Return the register number that __builtin_eh_return_regno would return with the specified argument.
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target,...
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008.
A template argument list.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
@ Type
The template argument is a type.
Symbolic representation of typeid(T) for some type T.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isAnyComplexType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
A memory block, either on the stack or in the heap.
const Descriptor * getDescriptor() const
Returns the block's descriptor.
Wrapper around boolean types.
static Boolean from(T Value)
Pointer into the code segment.
Compilation context for expressions.
Manages dynamic memory allocations done during bytecode interpretation.
const APFloat & getAPFloat() const
llvm::FPClassTest classify() const
ComparisonCategoryResult compare(const Floating &RHS) const
static Floating getInf(const llvm::fltSemantics &Sem)
static Floating abs(const Floating &F)
APFloat::fltCategory getCategory() const
Base class for stack frames, shared between VM and walker.
const FunctionDecl * getDecl() const
Returns the original FunctionDecl.
unsigned getBuiltinID() const
Frame storing local variables.
const Expr * getExpr(CodePtr PC) const
InterpFrame * Caller
The frame of the previous function.
CodePtr getRetPC() const
Returns the return address of the frame.
const FunctionDecl * getCallee() const override
Returns the caller.
Stack frame storing temporaries and parameters.
void clear()
Clears the stack without calling any destructors.
T & peek() const
Returns a reference to the value on the top of the stack.
A pointer to a memory block, live or dead.
bool isInitialized() const
Checks if an object was initialized.
Pointer atIndex(uint64_t Idx) const
Offsets a pointer inside an array.
bool isDummy() const
Checks if the pointer points to a dummy value.
int64_t getIndex() const
Returns the index into an array.
bool isActive() const
Checks if the object is active.
Pointer atField(unsigned Off) const
Creates a pointer to a field.
T & deref() const
Dereferences the pointer, if it's live.
unsigned getNumElems() const
Returns the number of elements.
void activate() const
Activats a field.
bool isIntegralPointer() const
QualType getType() const
Returns the type of the innermost field.
bool isLive() const
Checks if the pointer is live.
uint64_t getByteOffset() const
Returns the byte offset from the start.
std::string toDiagnosticString(const ASTContext &Ctx) const
Converts the pointer to a string usable in diagnostics.
bool isZero() const
Checks if the pointer is null.
const Descriptor * getDeclDesc() const
Accessor for information about the declaration site.
static bool pointToSameBlock(const Pointer &A, const Pointer &B)
Checks if both given pointers point to the same block.
APValue toAPValue(const ASTContext &ASTCtx) const
Converts the pointer to an APValue.
uint64_t getIntegerRepresentation() const
bool isBlockPointer() const
const Block * block() const
const Descriptor * getFieldDesc() const
Accessors for information about the innermost field.
size_t elemSize() const
Returns the element size of the innermost field.
void initialize() const
Initializes a field.
const Record * getRecord() const
Returns the record descriptor of a class.
Structure/Class descriptor.
bool isUnion() const
Checks if the record is a union.
const Field * getField(const FieldDecl *FD) const
Returns a field.
llvm::iterator_range< const_base_iter > bases() const
unsigned getNumFields() const
llvm::iterator_range< const_field_iter > fields() const
Describes the statement/declaration an opcode was generated from.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool __atomic_always_lock_free(size_t, void const volatile*) bool __atomic_is_lock_free(size_t,...
bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr, BitcastBuffer &Buffer, bool ReturnOnUninit)
static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset=0)
Peek an integer value from the stack into an APSInt.
static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static PrimType getLongPrimType(const InterpState &S)
static bool interp__builtin_assume_aligned(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
__builtin_assume_aligned(Ptr, Alignment[, ExtraOffset])
bool CheckNewDeleteForms(InterpState &S, CodePtr OpPC, DynamicAllocator::Form AllocForm, DynamicAllocator::Form DeleteForm, const Descriptor *D, const Expr *NewExpr)
Diagnose mismatched new[]/delete or new/delete[] pairs.
static bool interp__builtin_operator_delete(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp_floating_comparison(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, llvm::ArrayRef< int64_t > ArrayIndices, int64_t &Result)
Interpret an offsetof operation.
static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, bool Signaling)
bool SetThreeWayComparisonField(InterpState &S, CodePtr OpPC, const Pointer &Ptr, const APSInt &IntValue)
Sets the given integral value to the pointer, which is of a std::{weak,partial,strong}_ordering type.
static bool interp__builtin_ptrauth_string_discriminator(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool retPrimValue(InterpState &S, CodePtr OpPC, std::optional< PrimType > &T)
static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func)
static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_carryop(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
Three integral values followed by a pointer (lhs, rhs, carry, carryOut).
static bool interp__builtin_signbit(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool interp__builtin_arithmetic_fence(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_inf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
static bool interp__builtin_ia32_bzhi(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static unsigned callArgSize(const InterpState &S, const CallExpr *C)
static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool interp__builtin_vector_reduce(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_os_log_format_buffer_size(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_clz(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
__builtin_is_aligned() __builtin_align_up() __builtin_align_down() The first parameter is either an i...
static bool interp__builtin_clrsb(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_constant_p(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_eh_return_data_regno(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool RetVoid(InterpState &S, CodePtr &PC)
static bool isOneByteCharacterType(QualType T)
Determine if T is a character type for which we guarantee that sizeof(T) == 1.
static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a value can be loaded from a block.
static bool interp__builtin_abs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static T getParam(const InterpFrame *Frame, unsigned Index)
static bool interp__builtin_ia32_lzcnt(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is in range.
bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is live and accessible.
static bool interp__builtin_ia32_pext(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_overflowop(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_elementwise_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
Can be called with an integer or vector as the first and only parameter.
static bool handleOverflow(InterpState &S, CodePtr OpPC, const T &SrcValue)
PrimType
Enumeration of the primitive types of the VM.
static bool interp__builtin_isfinite(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool copyComposite(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest, bool Activate)
static bool interp__builtin_issubnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool interp__builtin_isinf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, bool CheckSign, const CallExpr *Call)
static bool interp__builtin_move(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, bool IsNumBuiltin)
static APSInt getAPSIntParam(const InterpFrame *Frame, unsigned Index)
static bool noopPointer(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
Just takes the first Argument to the call and puts it on the stack.
static void pushInteger(InterpState &S, const APSInt &Val, QualType QT)
Pushes Val on the stack as the type given by QT.
static bool interp__builtin_issignaling(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
bool CheckArray(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if the array is offsetable.
static bool interp__builtin_complex(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
__builtin_complex(Float A, float B);
static bool interp__builtin_ia32_tzcnt(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_parity(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is a dummy pointer.
static bool interp__builtin_ctz(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_iszero(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool interp__builtin_ia32_pdep(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static PrimType getIntPrimType(const InterpState &S)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
static void assignInteger(Pointer &Dest, PrimType ValueT, const APSInt &Value)
static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_expect(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call, uint32_t BuiltinID)
Interpret a builtin function.
static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
Five int values followed by one floating value.
static bool interp__builtin_ia32_bextr(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, bool IsNumBuiltin)
static bool interp__builtin_isnan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
Defined as __builtin_isnan(...), to accommodate the fact that it can take a float,...
bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest)
Copy the contents of Src into Dest.
static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call, bool Right)
rotateleft(value, amount)
constexpr bool isIntegralType(PrimType T)
static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
First parameter to __builtin_isfpclass is the floating value, the second one is an integral value.
static void diagnoseNonConstexprBuiltin(InterpState &S, CodePtr OpPC, unsigned ID)
static bool interp__builtin_addressof(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_bitreverse(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_ia32_addcarry_subborrow(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static void swapBytes(std::byte *M, size_t N)
static bool interp__builtin_bswap(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ Result
The result type of a method or function.
const FunctionProtoType * T
Track what bits have been initialized to known values and which ones have indeterminate value.
std::unique_ptr< std::byte[]> Data
size_t getQuantity() const
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
QualType getElemQualType() const
const ValueDecl * asValueDecl() const
static constexpr unsigned MaxArrayElemBytes
Maximum number of bytes to be used for array elements.
static constexpr MetadataSize InlineDescMD
unsigned getElemSize() const
returns the size of an element when the structure is viewed as an array.
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
PrimType getPrimType() const
bool isRecord() const
Checks if the descriptor is of a record.
const Record *const ElemRecord
Pointer to the record, if block contains records.
const Expr * asExpr() const
bool isArray() const
Checks if the descriptor is of an array.