8#include "../ExprConstShared.h"
20#include "llvm/ADT/StringExtras.h"
21#include "llvm/Support/SipHash.h"
29 for (
const Expr *
E :
C->arguments()) {
38 assert(
Frame->getFunction()->getNumParams() > Index);
39 unsigned Offset =
Frame->getFunction()->getParamOffset(Index);
40 return Frame->getParam<
T>(Offset);
45 unsigned Offset =
Frame->getFunction()->getParamOffset(Index);
47 R =
Frame->getParam<
T>(Offset).toAPSInt());
57 else if (IntWidth == 16)
59 llvm_unreachable(
"Int isn't 16 or 32 bit?");
68 else if (LongWidth == 32)
70 else if (LongWidth == 16)
72 llvm_unreachable(
"long isn't 16, 32 or 64 bit?");
90 std::optional<PrimType>
T = S.getContext().classify(QT);
95 int64_t
V = Val.getSExtValue();
99 uint64_t
V = Val.getZExtValue();
106 if constexpr (std::is_same_v<T, APInt>)
108 else if constexpr (std::is_same_v<T, APSInt>)
113 std::is_signed_v<T>),
114 !std::is_signed_v<T>),
120 ValueT, { Dest.
deref<
T>() = T::from(
static_cast<T>(
Value)); });
124 std::optional<PrimType> &
T) {
130 return Ret<X>(S, OpPC);
147 llvm_unreachable(
"Unsupported return type for builtin function");
154 auto Loc = S.Current->getSource(OpPC);
156 S.CCEDiag(
Loc, diag::note_constexpr_invalid_function)
160 S.CCEDiag(
Loc, diag::note_invalid_subexpr_in_const_expr);
166 unsigned Depth = S.Current->getDepth();
168 return F && F->isInStdNamespace() && F->getIdentifier() &&
169 F->getIdentifier()->isStr(
"is_constant_evaluated");
174 if (S.inConstantContext() && !S.checkingPotentialConstantExpression() &&
175 S.getEvalStatus().
Diag &&
176 (Depth == 1 || (Depth == 2 && isStdCall(Caller->
getCallee())))) {
180 diag::warn_is_constant_evaluated_always_true_constexpr)
185 diag::warn_is_constant_evaluated_always_true_constexpr)
197 unsigned ID =
Func->getBuiltinID();
201 if (ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp)
204 uint64_t Limit = ~static_cast<uint64_t>(0);
205 if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp)
227 for (;; ++IndexA, ++IndexB, ++Steps) {
237 uint8_t CA = PA.
deref<uint8_t>();
238 uint8_t CB = PB.
deref<uint8_t>();
243 }
else if (CA < CB) {
247 if (CA == 0 || CB == 0)
258 unsigned ID =
Func->getBuiltinID();
261 if (ID == Builtin::BIstrlen || ID == Builtin::BIwcslen)
276 if (ID == Builtin::BI__builtin_wcslen || ID == Builtin::BIwcslen) {
278 assert(ElemSize == AC.getTypeSizeInChars(AC.getWCharType()).getQuantity());
282 for (
size_t I = StrPtr.
getIndex();; ++I, ++Len) {
291 Val = ElemPtr.
deref<uint8_t>();
294 Val = ElemPtr.
deref<uint16_t>();
297 Val = ElemPtr.
deref<uint32_t>();
300 llvm_unreachable(
"Unsupported char size");
325 for (
unsigned I = 0;; ++I) {
331 if (Elem.
deref<int8_t>() == 0)
334 Str += Elem.
deref<
char>();
339 Fill = llvm::APInt(32, 0);
340 else if (StringRef(Str).getAsInteger(0, Fill))
343 const llvm::fltSemantics &TargetSemantics =
350 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
353 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
362 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
365 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
374 const llvm::fltSemantics &TargetSemantics =
408 else if (LHS.
isNan() || RHS < LHS)
432 else if (LHS.
isNan() || RHS > LHS)
468 bool IsInf = Arg.
isInf();
535 case Builtin::BI__builtin_isgreater:
537 case Builtin::BI__builtin_isgreaterequal:
539 case Builtin::BI__builtin_isless:
541 case Builtin::BI__builtin_islessequal:
543 case Builtin::BI__builtin_islessgreater: {
548 case Builtin::BI__builtin_isunordered:
551 llvm_unreachable(
"Unexpected builtin ID: Should be a floating point "
552 "comparison function");
565 PrimType FPClassArgT = *S.getContext().classify(
Call->getArg(1)->getType());
571 static_cast<int32_t
>((F.
classify() & FPClassArg).getZExtValue());
589 case APFloat::fcInfinity:
592 case APFloat::fcNormal:
595 case APFloat::fcZero:
628 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
631 APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
false))
633 if (Val.isNegative())
643 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
652 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
661 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
663 pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(),
Call->getType());
671 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
682 assert(
Call->getNumArgs() == 1);
687 int32_t ReturnVal =
static_cast<int32_t
>(ResultClass);
699 unsigned NumArgs =
Call->getNumArgs();
700 assert(NumArgs == 2 || NumArgs == 3);
702 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
717 PrimType AmountT = *S.getContext().classify(
Call->getArg(1)->getType());
718 PrimType ValueT = *S.getContext().classify(
Call->getArg(0)->getType());
739 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
742 uint64_t N =
Value.countr_zero();
751 assert(
Call->getArg(0)->isLValue());
757 }
else if (PtrT ==
PT_Ptr) {
761 assert(
false &&
"Unsupported pointer type passed to __builtin_addressof()");
772 TYPE_SWITCH(ArgT,
const T &Arg = S.Stk.peek<
T>(); S.Stk.push<
T>(Arg););
774 return Func->getDecl()->isConstexpr();
781 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
807 unsigned BuiltinOp =
Func->getBuiltinID();
808 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
809 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
815 QualType ResultType =
Call->getArg(2)->getType()->getPointeeType();
816 PrimType ResultT = *S.getContext().classify(ResultType);
820 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
821 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
822 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
823 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
825 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
827 uint64_t LHSSize = LHS.getBitWidth();
828 uint64_t RHSSize = RHS.getBitWidth();
830 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
836 if (IsSigned && !AllSigned)
839 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
840 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
847 llvm_unreachable(
"Invalid value for BuiltinOp");
848 case Builtin::BI__builtin_add_overflow:
849 case Builtin::BI__builtin_sadd_overflow:
850 case Builtin::BI__builtin_saddl_overflow:
851 case Builtin::BI__builtin_saddll_overflow:
852 case Builtin::BI__builtin_uadd_overflow:
853 case Builtin::BI__builtin_uaddl_overflow:
854 case Builtin::BI__builtin_uaddll_overflow:
855 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, Overflow)
856 : LHS.uadd_ov(RHS, Overflow);
858 case Builtin::BI__builtin_sub_overflow:
859 case Builtin::BI__builtin_ssub_overflow:
860 case Builtin::BI__builtin_ssubl_overflow:
861 case Builtin::BI__builtin_ssubll_overflow:
862 case Builtin::BI__builtin_usub_overflow:
863 case Builtin::BI__builtin_usubl_overflow:
864 case Builtin::BI__builtin_usubll_overflow:
865 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, Overflow)
866 : LHS.usub_ov(RHS, Overflow);
868 case Builtin::BI__builtin_mul_overflow:
869 case Builtin::BI__builtin_smul_overflow:
870 case Builtin::BI__builtin_smull_overflow:
871 case Builtin::BI__builtin_smulll_overflow:
872 case Builtin::BI__builtin_umul_overflow:
873 case Builtin::BI__builtin_umull_overflow:
874 case Builtin::BI__builtin_umulll_overflow:
875 Result = LHS.isSigned() ? LHS.smul_ov(RHS, Overflow)
876 : LHS.umul_ov(RHS, Overflow);
882 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
883 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
884 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
892 if (!APSInt::isSameValue(Temp,
Result))
900 assert(
Func->getDecl()->getReturnType()->isBooleanType());
910 unsigned BuiltinOp =
Func->getBuiltinID();
911 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
912 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
913 PrimType CarryT = *S.getContext().classify(
Call->getArg(2)->getType());
930 bool FirstOverflowed =
false;
931 bool SecondOverflowed =
false;
934 llvm_unreachable(
"Invalid value for BuiltinOp");
935 case Builtin::BI__builtin_addcb:
936 case Builtin::BI__builtin_addcs:
937 case Builtin::BI__builtin_addc:
938 case Builtin::BI__builtin_addcl:
939 case Builtin::BI__builtin_addcll:
941 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
943 case Builtin::BI__builtin_subcb:
944 case Builtin::BI__builtin_subcs:
945 case Builtin::BI__builtin_subc:
946 case Builtin::BI__builtin_subcl:
947 case Builtin::BI__builtin_subcll:
949 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
954 CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed);
957 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
958 PrimType CarryOutT = *S.getContext().classify(CarryOutType);
962 assert(
Call->getType() ==
Call->getArg(0)->getType());
971 unsigned BuiltinOp =
Func->getBuiltinID();
972 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
977 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
978 BuiltinOp != Builtin::BI__lzcnt &&
979 BuiltinOp != Builtin::BI__lzcnt64;
982 if (
Func->getBuiltinID() == Builtin::BI__builtin_clzg &&
983 Call->getNumArgs() == 2) {
985 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
1003 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
1007 if (
Func->getBuiltinID() == Builtin::BI__builtin_ctzg &&
1008 Call->getNumArgs() == 2) {
1010 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
1025 PrimType ReturnT = *S.getContext().classify(
Call->getType());
1026 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
1028 assert(Val.getActiveBits() <= 64);
1031 { S.Stk.push<
T>(T::from(Val.byteSwap().getZExtValue())); });
1042 unsigned BuiltinOp =
Func->getBuiltinID();
1044 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
1045 unsigned SizeValOffset = 0;
1046 if (BuiltinOp != Builtin::BI__c11_atomic_is_lock_free)
1050 auto returnBool = [&S](
bool Value) ->
bool {
1066 if (Size.isPowerOfTwo()) {
1068 unsigned InlineWidthBits =
1074 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
1076 return returnBool(
true);
1079 assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);
1082 return returnBool(
true);
1086 if (
APSInt(
APInt(64, IntVal,
false),
true).isAligned(Size.getAsAlign()))
1087 return returnBool(
true);
1090 const Expr *PtrArg =
Call->getArg(1);
1092 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
1095 if (ICE->getCastKind() == CK_BitCast)
1096 PtrArg = ICE->getSubExpr();
1104 return returnBool(
true);
1110 if (BuiltinOp == Builtin::BI__atomic_always_lock_free)
1111 return returnBool(
false);
1127 Result.atIndex(0).initialize();
1129 Result.atIndex(1).initialize();
1144 unsigned BuiltinOp =
Func->getBuiltinID();
1147 PrimType AlignmentT = *S.Ctx.classify(
Call->getArg(1));
1150 if (Alignment < 0 || !Alignment.isPowerOf2()) {
1151 S.FFDiag(
Call, diag::note_constexpr_invalid_alignment) << Alignment;
1155 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
1156 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
1157 S.FFDiag(
Call, diag::note_constexpr_alignment_too_big)
1158 << MaxValue <<
Call->getArg(0)->getType() << Alignment;
1168 APSInt Align = Alignment.extOrTrunc(Src.getBitWidth());
1169 if (BuiltinOp == Builtin::BI__builtin_align_up) {
1171 APSInt((Src + (Align - 1)) & ~(Align - 1), Src.isUnsigned());
1173 }
else if (BuiltinOp == Builtin::BI__builtin_align_down) {
1174 APSInt AlignedVal =
APSInt(Src & ~(Align - 1), Src.isUnsigned());
1177 assert(*S.Ctx.classify(
Call->getType()) ==
PT_Bool);
1178 S.Stk.push<
Boolean>((Src & (Align - 1)) == 0);
1183 assert(FirstArgT ==
PT_Ptr);
1193 if (BuiltinOp == Builtin::BI__builtin_is_aligned) {
1208 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_compute)
1213 assert(BuiltinOp == Builtin::BI__builtin_align_down ||
1214 BuiltinOp == Builtin::BI__builtin_align_up);
1229 assert(Alignment.getBitWidth() <= 64 &&
1230 "Cannot handle > 64-bit address-space");
1231 uint64_t Alignment64 = Alignment.getZExtValue();
1234 ? llvm::alignDown(PtrOffset, Alignment64)
1235 : llvm::alignTo(PtrOffset, Alignment64));
1242 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;
1251 assert(
Call->getNumArgs() == 2 ||
Call->getNumArgs() == 3);
1254 std::optional<PrimType> PtrT = S.Ctx.classify(
Call->getArg(0));
1260 std::optional<APSInt> ExtraOffset;
1262 if (
Call->getNumArgs() == 2) {
1265 PrimType AlignmentT = *S.Ctx.classify(
Call->getArg(1));
1266 PrimType ExtraOffsetT = *S.Ctx.classify(
Call->getArg(2));
1283 if (BaseAlignment < Align) {
1284 S.CCEDiag(
Call->getArg(0),
1285 diag::note_constexpr_baa_insufficient_alignment)
1295 if (AVOffset.
alignTo(Align) != AVOffset) {
1297 S.CCEDiag(
Call->getArg(0),
1298 diag::note_constexpr_baa_insufficient_alignment)
1301 S.CCEDiag(
Call->getArg(0),
1302 diag::note_constexpr_baa_value_insufficient_alignment)
1315 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1316 !
Call->getArg(1)->getType()->isIntegerType())
1325 unsigned BitWidth = Val.getBitWidth();
1326 uint64_t Shift = Index.extractBitsAsZExtValue(8, 0);
1327 uint64_t Length = Index.extractBitsAsZExtValue(8, 8);
1328 Length = Length > BitWidth ? BitWidth : Length;
1331 if (Length == 0 || Shift >= BitWidth) {
1336 uint64_t
Result = Val.getZExtValue() >> Shift;
1337 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
1347 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1348 !
Call->getArg(1)->getType()->isIntegerType() ||
1359 unsigned BitWidth = Val.getBitWidth();
1360 uint64_t Index = Idx.extractBitsAsZExtValue(8, 0);
1362 if (Index < BitWidth)
1363 Val.clearHighBits(BitWidth - Index);
1375 !
Call->getArg(0)->getType()->isIntegerType())
1379 pushInteger(S, Val.countLeadingZeros(), CallType);
1389 !
Call->getArg(0)->getType()->isIntegerType())
1393 pushInteger(S, Val.countTrailingZeros(), CallType);
1401 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1402 !
Call->getArg(1)->getType()->isIntegerType())
1412 unsigned BitWidth = Val.getBitWidth();
1414 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I) {
1416 Result.setBitVal(I, Val[
P++]);
1426 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1427 !
Call->getArg(1)->getType()->isIntegerType())
1437 unsigned BitWidth = Val.getBitWidth();
1439 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I) {
1441 Result.setBitVal(
P++, Val[I]);
1452 if (
Call->getNumArgs() != 4 || !
Call->getArg(0)->getType()->isIntegerType() ||
1453 !
Call->getArg(1)->getType()->isIntegerType() ||
1454 !
Call->getArg(2)->getType()->isIntegerType())
1457 unsigned BuiltinOp =
Func->getBuiltinID();
1462 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
1463 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
1465 unsigned BitWidth = LHS.getBitWidth();
1466 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
1468 IsAdd ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
1469 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
1473 APSInt(ExResult.extractBits(1, BitWidth),
true);
1476 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
1477 PrimType CarryOutT = *S.getContext().classify(CarryOutType);
1499 const auto &Ptr = S.Stk.peek<
Pointer>();
1500 assert(Ptr.getFieldDesc()->isPrimitiveArray());
1502 StringRef R(&Ptr.deref<
char>(), Ptr.getFieldDesc()->getNumElems() - 1);
1503 uint64_t
Result = getPointerAuthStableSipHash(R);
1519 auto returnInt = [&S,
Call](
bool Value) ->
bool {
1543 auto Res =
C.interpretExpr(Arg, Arg->
isGLValue());
1544 if (Res.isInvalid()) {
1547 return returnInt(
false);
1551 const APValue &LV = Res.toAPValue();
1554 if (
Base.isNull()) {
1556 return returnInt(
true);
1557 }
else if (
const auto *
E =
Base.dyn_cast<
const Expr *>()) {
1558 if (!isa<StringLiteral>(
E))
1559 return returnInt(
false);
1564 return returnInt(
true);
1567 return returnInt(
false);
1573 return returnInt(
true);
1576 return returnInt(
false);
1592 const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
Func->getDecl());
1596 if (!FnII || !FnII->
isStr(
"allocate"))
1600 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1606 if (CTSD->isInStdNamespace() && ClassII && ClassII->
isStr(
"allocator") &&
1608 ElemType = TAL[0].getAsType();
1615 ? diag::note_constexpr_new_untyped
1616 : diag::note_constexpr_new);
1621 S.FFDiag(
Call, diag::note_constexpr_new_not_complete_object_type)
1628 assert(!ElemSize.
isZero());
1631 APInt NumElems, Remainder;
1633 APInt::udivrem(
Bytes, ElemSizeAP, NumElems, Remainder);
1634 if (Remainder != 0) {
1636 S.FFDiag(
Call, diag::note_constexpr_operator_new_bad_size)
1642 if (NumElems.getActiveBits() >
1647 S.FFDiag(
Loc, diag::note_constexpr_new_too_large)
1648 << NumElems.getZExtValue();
1652 std::optional<PrimType> ElemT = S.getContext().classify(ElemType);
1655 if (NumElems.ule(1)) {
1660 Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),
1667 assert(NumElems.ugt(1));
1670 Allocator.allocate(
Call, *ElemT, NumElems.getZExtValue(),
1679 const Descriptor *Desc = S.P.createDescriptor(
1681 false,
false,
false,
1684 if (NumElems.ule(1)) {
1685 Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),
1693 Allocator.allocate(Desc, NumElems.getZExtValue(), S.Ctx.getEvalID(),
1704 const Expr *Source =
nullptr;
1705 const Block *BlockToDelete =
nullptr;
1711 S.CCEDiag(
Call, diag::note_constexpr_deallocate_null);
1716 BlockToDelete = Ptr.
block();
1718 assert(BlockToDelete);
1722 std::optional<DynamicAllocator::Form> AllocForm =
1723 Allocator.getAllocationForm(Source);
1725 if (!Allocator.deallocate(Source, BlockToDelete, S)) {
1728 S.FFDiag(
Loc, diag::note_constexpr_double_delete);
1753 unsigned ID =
Func->getBuiltinID();
1755 assert(
Call->getType() == ElemType);
1756 PrimType ElemT = *S.getContext().classify(ElemType);
1761 unsigned BitWidth =
Result.bitWidth();
1762 for (
unsigned I = 1; I != NumElems; ++I) {
1763 T Elem = Arg.
atIndex(I).deref<T>();
1766 if (ID == Builtin::BI__builtin_reduce_add) {
1768 unsigned OverflowBits = BitWidth + 1;
1770 (PrevResult.toAPSInt(OverflowBits) +
1771 Elem.toAPSInt(OverflowBits)));
1774 }
else if (ID == Builtin::BI__builtin_reduce_mul) {
1776 unsigned OverflowBits = BitWidth * 2;
1778 (PrevResult.toAPSInt(OverflowBits) *
1779 Elem.toAPSInt(OverflowBits)));
1783 }
else if (ID == Builtin::BI__builtin_reduce_and) {
1785 }
else if (ID == Builtin::BI__builtin_reduce_or) {
1787 }
else if (ID == Builtin::BI__builtin_reduce_xor) {
1790 llvm_unreachable(
"Unhandled vector reduce builtin");
1804 assert(
Call->getNumArgs() == 1);
1805 if (
Call->getArg(0)->getType()->isIntegerType()) {
1806 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
1812 assert(
Call->getArg(0)->getType()->isVectorType());
1821 PrimType ElemT = *S.getContext().classify(ElemType);
1825 for (
unsigned I = 0; I != NumElems; ++I) {
1839 assert(
Call->getNumArgs() == 3);
1840 unsigned ID =
Func->getBuiltinID();
1846 assert(!Size.isSigned() &&
"memcpy and friends take an unsigned size");
1848 if (ID == Builtin::BImemcpy || ID == Builtin::BImemmove)
1851 bool Move = (ID == Builtin::BI__builtin_memmove || ID == Builtin::BImemmove);
1854 if (Size.isZero()) {
1861 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_null)
1862 << Move <<
false << !SrcPtr.
isZero()
1872 size_t RemainingDestElems;
1879 DestElemType = DestPtr.
getType();
1880 RemainingDestElems = 1;
1884 if (Size.urem(DestElemSize) != 0) {
1885 S.FFDiag(S.Current->getSource(OpPC),
1886 diag::note_constexpr_memcpy_unsupported)
1887 << Move <<
false << 0 << DestElemType << Size
1893 size_t RemainingSrcElems;
1900 SrcElemType = SrcPtr.
getType();
1901 RemainingSrcElems = 1;
1906 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_type_pun)
1907 << Move << SrcElemType << DestElemType;
1912 size_t RemainingDestBytes = RemainingDestElems * DestElemSize;
1913 size_t RemainingSrcBytes = RemainingSrcElems * SrcElemSize;
1914 if (Size.ugt(RemainingDestBytes) || Size.ugt(RemainingSrcBytes)) {
1915 APInt N = Size.udiv(DestElemSize);
1916 S.FFDiag(S.Current->getSource(OpPC),
1917 diag::note_constexpr_memcpy_unsupported)
1918 << Move <<
false << (Size.ugt(RemainingSrcBytes) ? 1 : 2)
1919 << DestElemType <<
toString(N, 10,
false);
1927 unsigned N = Size.getZExtValue();
1929 if ((SrcIndex <= DstIndex && (SrcIndex + N) > DstIndex) ||
1930 (DstIndex <= SrcIndex && (DstIndex + N) > SrcIndex)) {
1931 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_overlap)
1937 assert(Size.getZExtValue() % DestElemSize == 0);
1954 assert(
Call->getNumArgs() == 3);
1955 unsigned ID =
Func->getBuiltinID();
1961 if (ID == Builtin::BImemcmp || ID == Builtin::BIbcmp ||
1962 ID == Builtin::BIwmemcmp)
1965 if (Size.isZero()) {
1971 (ID == Builtin::BIwmemcmp || ID == Builtin::BI__builtin_wmemcmp);
1978 S.FFDiag(S.Current->getSource(OpPC),
1979 diag::note_constexpr_memcmp_unsupported)
2008 unsigned ElemSize = 1;
2013 size_t ByteSize = Size.getZExtValue() * ElemSize;
2014 size_t CmpSize = std::min(MinBufferSize, ByteSize);
2016 for (
size_t I = 0; I != CmpSize; I += ElemSize) {
2019 T A = *reinterpret_cast<T *>(BufferA.Data.get() + I);
2020 T B = *reinterpret_cast<T *>(BufferB.Data.get() + I);
2022 pushInteger(S, -1, Call->getType());
2030 std::byte A = BufferA.
Data[I];
2031 std::byte B = BufferB.
Data[I];
2045 if (ByteSize <= CmpSize) {
2054 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_past_end)
2055 <<
AK_Read << S.Current->getRange(OpPC);
2063 std::optional<PrimType> ReturnT = S.getContext().classify(
Call);
2065 switch (BuiltinID) {
2066 case Builtin::BI__builtin_is_constant_evaluated:
2070 case Builtin::BI__builtin_assume:
2071 case Builtin::BI__assume:
2073 case Builtin::BI__builtin_strcmp:
2074 case Builtin::BIstrcmp:
2075 case Builtin::BI__builtin_strncmp:
2076 case Builtin::BIstrncmp:
2080 case Builtin::BI__builtin_strlen:
2081 case Builtin::BIstrlen:
2082 case Builtin::BI__builtin_wcslen:
2083 case Builtin::BIwcslen:
2087 case Builtin::BI__builtin_nan:
2088 case Builtin::BI__builtin_nanf:
2089 case Builtin::BI__builtin_nanl:
2090 case Builtin::BI__builtin_nanf16:
2091 case Builtin::BI__builtin_nanf128:
2095 case Builtin::BI__builtin_nans:
2096 case Builtin::BI__builtin_nansf:
2097 case Builtin::BI__builtin_nansl:
2098 case Builtin::BI__builtin_nansf16:
2099 case Builtin::BI__builtin_nansf128:
2104 case Builtin::BI__builtin_huge_val:
2105 case Builtin::BI__builtin_huge_valf:
2106 case Builtin::BI__builtin_huge_vall:
2107 case Builtin::BI__builtin_huge_valf16:
2108 case Builtin::BI__builtin_huge_valf128:
2109 case Builtin::BI__builtin_inf:
2110 case Builtin::BI__builtin_inff:
2111 case Builtin::BI__builtin_infl:
2112 case Builtin::BI__builtin_inff16:
2113 case Builtin::BI__builtin_inff128:
2117 case Builtin::BI__builtin_copysign:
2118 case Builtin::BI__builtin_copysignf:
2119 case Builtin::BI__builtin_copysignl:
2120 case Builtin::BI__builtin_copysignf128:
2125 case Builtin::BI__builtin_fmin:
2126 case Builtin::BI__builtin_fminf:
2127 case Builtin::BI__builtin_fminl:
2128 case Builtin::BI__builtin_fminf16:
2129 case Builtin::BI__builtin_fminf128:
2134 case Builtin::BI__builtin_fminimum_num:
2135 case Builtin::BI__builtin_fminimum_numf:
2136 case Builtin::BI__builtin_fminimum_numl:
2137 case Builtin::BI__builtin_fminimum_numf16:
2138 case Builtin::BI__builtin_fminimum_numf128:
2143 case Builtin::BI__builtin_fmax:
2144 case Builtin::BI__builtin_fmaxf:
2145 case Builtin::BI__builtin_fmaxl:
2146 case Builtin::BI__builtin_fmaxf16:
2147 case Builtin::BI__builtin_fmaxf128:
2152 case Builtin::BI__builtin_fmaximum_num:
2153 case Builtin::BI__builtin_fmaximum_numf:
2154 case Builtin::BI__builtin_fmaximum_numl:
2155 case Builtin::BI__builtin_fmaximum_numf16:
2156 case Builtin::BI__builtin_fmaximum_numf128:
2161 case Builtin::BI__builtin_isnan:
2165 case Builtin::BI__builtin_issignaling:
2170 case Builtin::BI__builtin_isinf:
2175 case Builtin::BI__builtin_isinf_sign:
2180 case Builtin::BI__builtin_isfinite:
2184 case Builtin::BI__builtin_isnormal:
2188 case Builtin::BI__builtin_issubnormal:
2192 case Builtin::BI__builtin_iszero:
2196 case Builtin::BI__builtin_signbit:
2197 case Builtin::BI__builtin_signbitf:
2198 case Builtin::BI__builtin_signbitl:
2202 case Builtin::BI__builtin_isgreater:
2203 case Builtin::BI__builtin_isgreaterequal:
2204 case Builtin::BI__builtin_isless:
2205 case Builtin::BI__builtin_islessequal:
2206 case Builtin::BI__builtin_islessgreater:
2207 case Builtin::BI__builtin_isunordered:
2211 case Builtin::BI__builtin_isfpclass:
2215 case Builtin::BI__builtin_fpclassify:
2220 case Builtin::BI__builtin_fabs:
2221 case Builtin::BI__builtin_fabsf:
2222 case Builtin::BI__builtin_fabsl:
2223 case Builtin::BI__builtin_fabsf128:
2228 case Builtin::BI__builtin_abs:
2229 case Builtin::BI__builtin_labs:
2230 case Builtin::BI__builtin_llabs:
2235 case Builtin::BI__builtin_popcount:
2236 case Builtin::BI__builtin_popcountl:
2237 case Builtin::BI__builtin_popcountll:
2238 case Builtin::BI__builtin_popcountg:
2239 case Builtin::BI__popcnt16:
2240 case Builtin::BI__popcnt:
2241 case Builtin::BI__popcnt64:
2246 case Builtin::BI__builtin_parity:
2247 case Builtin::BI__builtin_parityl:
2248 case Builtin::BI__builtin_parityll:
2253 case Builtin::BI__builtin_clrsb:
2254 case Builtin::BI__builtin_clrsbl:
2255 case Builtin::BI__builtin_clrsbll:
2260 case Builtin::BI__builtin_bitreverse8:
2261 case Builtin::BI__builtin_bitreverse16:
2262 case Builtin::BI__builtin_bitreverse32:
2263 case Builtin::BI__builtin_bitreverse64:
2268 case Builtin::BI__builtin_classify_type:
2273 case Builtin::BI__builtin_expect:
2274 case Builtin::BI__builtin_expect_with_probability:
2279 case Builtin::BI__builtin_rotateleft8:
2280 case Builtin::BI__builtin_rotateleft16:
2281 case Builtin::BI__builtin_rotateleft32:
2282 case Builtin::BI__builtin_rotateleft64:
2283 case Builtin::BI_rotl8:
2284 case Builtin::BI_rotl16:
2285 case Builtin::BI_rotl:
2286 case Builtin::BI_lrotl:
2287 case Builtin::BI_rotl64:
2292 case Builtin::BI__builtin_rotateright8:
2293 case Builtin::BI__builtin_rotateright16:
2294 case Builtin::BI__builtin_rotateright32:
2295 case Builtin::BI__builtin_rotateright64:
2296 case Builtin::BI_rotr8:
2297 case Builtin::BI_rotr16:
2298 case Builtin::BI_rotr:
2299 case Builtin::BI_lrotr:
2300 case Builtin::BI_rotr64:
2305 case Builtin::BI__builtin_ffs:
2306 case Builtin::BI__builtin_ffsl:
2307 case Builtin::BI__builtin_ffsll:
2311 case Builtin::BIaddressof:
2312 case Builtin::BI__addressof:
2313 case Builtin::BI__builtin_addressof:
2318 case Builtin::BIas_const:
2319 case Builtin::BIforward:
2320 case Builtin::BIforward_like:
2321 case Builtin::BImove:
2322 case Builtin::BImove_if_noexcept:
2327 case Builtin::BI__builtin_eh_return_data_regno:
2332 case Builtin::BI__builtin_launder:
2337 case Builtin::BI__builtin_add_overflow:
2338 case Builtin::BI__builtin_sub_overflow:
2339 case Builtin::BI__builtin_mul_overflow:
2340 case Builtin::BI__builtin_sadd_overflow:
2341 case Builtin::BI__builtin_uadd_overflow:
2342 case Builtin::BI__builtin_uaddl_overflow:
2343 case Builtin::BI__builtin_uaddll_overflow:
2344 case Builtin::BI__builtin_usub_overflow:
2345 case Builtin::BI__builtin_usubl_overflow:
2346 case Builtin::BI__builtin_usubll_overflow:
2347 case Builtin::BI__builtin_umul_overflow:
2348 case Builtin::BI__builtin_umull_overflow:
2349 case Builtin::BI__builtin_umulll_overflow:
2350 case Builtin::BI__builtin_saddl_overflow:
2351 case Builtin::BI__builtin_saddll_overflow:
2352 case Builtin::BI__builtin_ssub_overflow:
2353 case Builtin::BI__builtin_ssubl_overflow:
2354 case Builtin::BI__builtin_ssubll_overflow:
2355 case Builtin::BI__builtin_smul_overflow:
2356 case Builtin::BI__builtin_smull_overflow:
2357 case Builtin::BI__builtin_smulll_overflow:
2362 case Builtin::BI__builtin_addcb:
2363 case Builtin::BI__builtin_addcs:
2364 case Builtin::BI__builtin_addc:
2365 case Builtin::BI__builtin_addcl:
2366 case Builtin::BI__builtin_addcll:
2367 case Builtin::BI__builtin_subcb:
2368 case Builtin::BI__builtin_subcs:
2369 case Builtin::BI__builtin_subc:
2370 case Builtin::BI__builtin_subcl:
2371 case Builtin::BI__builtin_subcll:
2376 case Builtin::BI__builtin_clz:
2377 case Builtin::BI__builtin_clzl:
2378 case Builtin::BI__builtin_clzll:
2379 case Builtin::BI__builtin_clzs:
2380 case Builtin::BI__builtin_clzg:
2381 case Builtin::BI__lzcnt16:
2382 case Builtin::BI__lzcnt:
2383 case Builtin::BI__lzcnt64:
2388 case Builtin::BI__builtin_ctz:
2389 case Builtin::BI__builtin_ctzl:
2390 case Builtin::BI__builtin_ctzll:
2391 case Builtin::BI__builtin_ctzs:
2392 case Builtin::BI__builtin_ctzg:
2397 case Builtin::BI__builtin_bswap16:
2398 case Builtin::BI__builtin_bswap32:
2399 case Builtin::BI__builtin_bswap64:
2404 case Builtin::BI__atomic_always_lock_free:
2405 case Builtin::BI__atomic_is_lock_free:
2406 case Builtin::BI__c11_atomic_is_lock_free:
2411 case Builtin::BI__builtin_complex:
2416 case Builtin::BI__builtin_is_aligned:
2417 case Builtin::BI__builtin_align_up:
2418 case Builtin::BI__builtin_align_down:
2423 case Builtin::BI__builtin_assume_aligned:
2428 case clang::X86::BI__builtin_ia32_bextr_u32:
2429 case clang::X86::BI__builtin_ia32_bextr_u64:
2430 case clang::X86::BI__builtin_ia32_bextri_u32:
2431 case clang::X86::BI__builtin_ia32_bextri_u64:
2436 case clang::X86::BI__builtin_ia32_bzhi_si:
2437 case clang::X86::BI__builtin_ia32_bzhi_di:
2442 case clang::X86::BI__builtin_ia32_lzcnt_u16:
2443 case clang::X86::BI__builtin_ia32_lzcnt_u32:
2444 case clang::X86::BI__builtin_ia32_lzcnt_u64:
2449 case clang::X86::BI__builtin_ia32_tzcnt_u16:
2450 case clang::X86::BI__builtin_ia32_tzcnt_u32:
2451 case clang::X86::BI__builtin_ia32_tzcnt_u64:
2456 case clang::X86::BI__builtin_ia32_pdep_si:
2457 case clang::X86::BI__builtin_ia32_pdep_di:
2462 case clang::X86::BI__builtin_ia32_pext_si:
2463 case clang::X86::BI__builtin_ia32_pext_di:
2468 case clang::X86::BI__builtin_ia32_addcarryx_u32:
2469 case clang::X86::BI__builtin_ia32_addcarryx_u64:
2470 case clang::X86::BI__builtin_ia32_subborrow_u32:
2471 case clang::X86::BI__builtin_ia32_subborrow_u64:
2476 case Builtin::BI__builtin_os_log_format_buffer_size:
2481 case Builtin::BI__builtin_ptrauth_string_discriminator:
2486 case Builtin::BI__builtin_constant_p:
2491 case Builtin::BI__noop:
2495 case Builtin::BI__builtin_operator_new:
2500 case Builtin::BI__builtin_operator_delete:
2505 case Builtin::BI__arithmetic_fence:
2510 case Builtin::BI__builtin_reduce_add:
2511 case Builtin::BI__builtin_reduce_mul:
2512 case Builtin::BI__builtin_reduce_and:
2513 case Builtin::BI__builtin_reduce_or:
2514 case Builtin::BI__builtin_reduce_xor:
2519 case Builtin::BI__builtin_elementwise_popcount:
2524 case Builtin::BI__builtin_memcpy:
2525 case Builtin::BImemcpy:
2526 case Builtin::BI__builtin_memmove:
2527 case Builtin::BImemmove:
2532 case Builtin::BI__builtin_memcmp:
2533 case Builtin::BImemcmp:
2534 case Builtin::BI__builtin_bcmp:
2535 case Builtin::BIbcmp:
2536 case Builtin::BI__builtin_wmemcmp:
2537 case Builtin::BIwmemcmp:
2543 S.FFDiag(S.Current->getLocation(OpPC),
2544 diag::note_invalid_subexpr_in_const_expr)
2545 << S.Current->getRange(OpPC);
2555 int64_t &IntResult) {
2557 unsigned N =
E->getNumComponents();
2560 unsigned ArrayIndex = 0;
2562 for (
unsigned I = 0; I != N; ++I) {
2564 switch (
Node.getKind()) {
2575 assert(FieldIndex < RL.
getFieldCount() &&
"offsetof field in wrong type");
2584 int64_t Index = ArrayIndices[ArrayIndex];
2590 Result += Index * ElementSize;
2609 CurrentType = BaseSpec->
getType();
2619 llvm_unreachable(
"Dependent OffsetOfExpr?");
2623 IntResult =
Result.getQuantity();
2640 FieldPtr.
deref<
T>() = T::from(IntValue.getSExtValue()));
2645static bool copyComposite(InterpState &S, CodePtr OpPC,
const Pointer &Src,
2646 Pointer &Dest,
bool Activate);
2648 Pointer &Dest,
bool Activate =
false) {
2652 auto copyField = [&](
const Record::Field &F,
bool Activate) ->
bool {
2654 if (std::optional<PrimType> FT = S.Ctx.classify(F.Decl->getType())) {
2671 for (
const Record::Field &F : R->
fields()) {
2676 if (!copyField(F,
true))
2680 if (!copyField(F, Activate))
2685 for (
const Record::Base &B : R->
bases()) {
2687 if (!copyRecord(S, OpPC, Src.
atField(B.Offset), DestBase, Activate))
2696 Pointer &Dest,
bool Activate =
false) {
2708 for (
unsigned I = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
2719 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)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
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
std::string getQuotedName(unsigned ID) const
Return a quoted name for the specified builtin for use in diagnostics.
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.
bool isUnknownSizeArray() const
Checks if the structure is an array of unknown size.
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.