clang: lib/AST/ByteCode/InterpBuiltin.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8#include "../ExprConstShared.h"

20#include "llvm/ADT/StringExtras.h"

21#include "llvm/Support/SipHash.h"

22

24namespace interp {

25

27 unsigned O = 0;

28

29 for (const Expr *E : C->arguments()) {

31 }

32

33 return O;

34}

35

36template

38 assert(Frame->getFunction()->getNumParams() > Index);

39 unsigned Offset = Frame->getFunction()->getParamOffset(Index);

40 return Frame->getParam<T>(Offset);

41}

42

45 unsigned Offset = Frame->getFunction()->getParamOffset(Index);

47 R = Frame->getParam<T>(Offset).toAPSInt());

48 return R;

49}

50

54

55 if (IntWidth == 32)

57 else if (IntWidth == 16)

59 llvm_unreachable("Int isn't 16 or 32 bit?");

60}

61

65

66 if (LongWidth == 64)

68 else if (LongWidth == 32)

70 else if (LongWidth == 16)

72 llvm_unreachable("long isn't 16, 32 or 64 bit?");

73}

74

75

77 if (Offset == 0)

79

82

83 return R;

84}

85

86

90 std::optional T = S.getContext().classify(QT);

91 assert(T);

92

95 int64_t V = Val.getSExtValue();

97 } else {

99 uint64_t V = Val.getZExtValue();

101 }

102}

103

104template

106 if constexpr (std::is_same_v<T, APInt>)

108 else if constexpr (std::is_same_v<T, APSInt>)

110 else

112 APSInt(APInt(sizeof(T) * 8, static_cast<uint64_t>(Val),

113 std::is_signed_v),

114 !std::is_signed_v),

115 QT);

116}

117

120 ValueT, { Dest.deref<T>() = T::from(static_cast<T>(Value)); });

121}

122

124 std::optional &T) {

125 if (T)

127

128#define RET_CASE(X) \

129 case X: \

130 return Ret(S, OpPC);

131 switch (*T) {

146 default:

147 llvm_unreachable("Unsupported return type for builtin function");

148 }

149#undef RET_CASE

150}

151

153 unsigned ID) {

154 auto Loc = S.Current->getSource(OpPC);

156 S.CCEDiag(Loc, diag::note_constexpr_invalid_function)

157 << 0 << 0

159 else

160 S.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);

161}

162

166 unsigned Depth = S.Current->getDepth();

167 auto isStdCall = [](const FunctionDecl *F) -> bool {

168 return F && F->isInStdNamespace() && F->getIdentifier() &&

169 F->getIdentifier()->isStr("is_constant_evaluated");

170 };

172

173

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)

182 } else {

183 const Expr *E = Frame->Caller->getExpr(Frame->getRetPC());

185 diag::warn_is_constant_evaluated_always_true_constexpr)

186 << "__builtin_is_constant_evaluated" << E->getSourceRange();

187 }

188 }

189

191 return true;

192}

193

197 unsigned ID = Func->getBuiltinID();

198 const Pointer &A = getParam(Frame, 0);

199 const Pointer &B = getParam(Frame, 1);

200

201 if (ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp)

203

204 uint64_t Limit = ~static_cast<uint64_t>(0);

205 if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp)

206 Limit = peekToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2)))

207 .getZExtValue();

208

209 if (Limit == 0) {

211 return true;

212 }

213

215 return false;

216

218 return false;

219

222

223 unsigned IndexA = A.getIndex();

224 unsigned IndexB = B.getIndex();

226 uint64_t Steps = 0;

227 for (;; ++IndexA, ++IndexB, ++Steps) {

228

229 if (Steps >= Limit)

230 break;

235 return false;

236 }

237 uint8_t CA = PA.deref<uint8_t>();

238 uint8_t CB = PB.deref<uint8_t>();

239

240 if (CA > CB) {

242 break;

243 } else if (CA < CB) {

245 break;

246 }

247 if (CA == 0 || CB == 0)

248 break;

249 }

250

252 return true;

253}

254

258 unsigned ID = Func->getBuiltinID();

259 const Pointer &StrPtr = getParam(Frame, 0);

260

261 if (ID == Builtin::BIstrlen || ID == Builtin::BIwcslen)

263

265 return false;

266

268 return false;

269

271 return false;

272

275

276 if (ID == Builtin::BI__builtin_wcslen || ID == Builtin::BIwcslen) {

278 assert(ElemSize == AC.getTypeSizeInChars(AC.getWCharType()).getQuantity());

279 }

280

281 size_t Len = 0;

282 for (size_t I = StrPtr.getIndex();; ++I, ++Len) {

284

286 return false;

287

288 uint32_t Val;

289 switch (ElemSize) {

290 case 1:

291 Val = ElemPtr.deref<uint8_t>();

292 break;

293 case 2:

294 Val = ElemPtr.deref<uint16_t>();

295 break;

296 case 4:

297 Val = ElemPtr.deref<uint32_t>();

298 break;

299 default:

300 llvm_unreachable("Unsupported char size");

301 }

302 if (Val == 0)

303 break;

304 }

305

307

308 return true;

309}

310

313 bool Signaling) {

314 const Pointer &Arg = getParam(Frame, 0);

315

317 return false;

318

320

321

322 llvm::APInt Fill;

323 std::string Str;

325 for (unsigned I = 0;; ++I) {

327

329 return false;

330

331 if (Elem.deref<int8_t>() == 0)

332 break;

333

334 Str += Elem.deref<char>();

335 }

336

337

338 if (Str.empty())

339 Fill = llvm::APInt(32, 0);

340 else if (StringRef(Str).getAsInteger(0, Fill))

341 return false;

342

343 const llvm::fltSemantics &TargetSemantics =

345

348 if (Signaling)

350 llvm::APFloat::getSNaN(TargetSemantics, false, &Fill));

351 else

353 llvm::APFloat::getQNaN(TargetSemantics, false, &Fill));

354 } else {

355

356

357

358

359

360 if (Signaling)

362 llvm::APFloat::getQNaN(TargetSemantics, false, &Fill));

363 else

365 llvm::APFloat::getSNaN(TargetSemantics, false, &Fill));

366 }

367

369 return true;

370}

371

374 const llvm::fltSemantics &TargetSemantics =

376

378 return true;

379}

380

384 const Floating &Arg1 = getParam(Frame, 0);

385 const Floating &Arg2 = getParam(Frame, 1);

386

390

391 return true;

392}

393

396 bool IsNumBuiltin) {

397 const Floating &LHS = getParam(Frame, 0);

398 const Floating &RHS = getParam(Frame, 1);

399

401

402 if (IsNumBuiltin) {

404 } else {

405

408 else if (LHS.isNan() || RHS < LHS)

410 else

412 }

413

415 return true;

416}

417

420 bool IsNumBuiltin) {

421 const Floating &LHS = getParam(Frame, 0);

422 const Floating &RHS = getParam(Frame, 1);

423

425

426 if (IsNumBuiltin) {

428 } else {

429

432 else if (LHS.isNan() || RHS > LHS)

434 else

436 }

437

439 return true;

440}

441

442

443

444

449

451 return true;

452}

453

459

461 return true;

462}

463

468 bool IsInf = Arg.isInf();

469

470 if (CheckSign)

472 else

474 return true;

475}

476

481

483 return true;

484}

485

490

492 return true;

493}

494

500

502 return true;

503}

504

509

511 return true;

512}

513

518

520 return true;

521}

522

530

532 S,

533 [&] {

534 switch (ID) {

535 case Builtin::BI__builtin_isgreater:

536 return LHS > RHS;

537 case Builtin::BI__builtin_isgreaterequal:

538 return LHS >= RHS;

539 case Builtin::BI__builtin_isless:

540 return LHS < RHS;

541 case Builtin::BI__builtin_islessequal:

542 return LHS <= RHS;

543 case Builtin::BI__builtin_islessgreater: {

547 }

548 case Builtin::BI__builtin_isunordered:

550 default:

551 llvm_unreachable("Unexpected builtin ID: Should be a floating point "

552 "comparison function");

553 }

554 }(),

555 Call->getType());

556 return true;

557}

558

559

560

565 PrimType FPClassArgT = *S.getContext().classify(Call->getArg(1)->getType());

569

571 static_cast<int32_t>((F.classify() & FPClassArg).getZExtValue());

573

574 return true;

575}

576

577

583

584 unsigned Index;

586 case APFloat::fcNaN:

587 Index = 0;

588 break;

589 case APFloat::fcInfinity:

590 Index = 1;

591 break;

592 case APFloat::fcNormal:

594 break;

595 case APFloat::fcZero:

596 Index = 4;

597 break;

598 }

599

600

601 assert(Index <= 4);

603 unsigned Offset =

605

608 return true;

609}

610

611

612

613

614

615

619 const Floating &Val = getParam(Frame, 0);

620

622 return true;

623}

624

628 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());

630 if (Val ==

631 APSInt(APInt::getSignedMinValue(Val.getBitWidth()), false))

632 return false;

633 if (Val.isNegative())

634 Val.negate();

636 return true;

637}

638

643 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());

646 return true;

647}

648

652 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());

655 return true;

656}

657

661 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());

663 pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(), Call->getType());

664 return true;

665}

666

671 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());

674 return true;

675}

676

681

682 assert(Call->getNumArgs() == 1);

683 const Expr *Arg = Call->getArg(0);

684

687 int32_t ReturnVal = static_cast<int32_t>(ResultClass);

689 return true;

690}

691

692

693

697

698

699 unsigned NumArgs = Call->getNumArgs();

700 assert(NumArgs == 2 || NumArgs == 3);

701

702 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());

704 if (NumArgs == 3)

706

709 return true;

710}

711

712

717 PrimType AmountT = *S.getContext().classify(Call->getArg(1)->getType());

718 PrimType ValueT = *S.getContext().classify(Call->getArg(0)->getType());

719

723

727 true);

728 else

730 true);

731

733 return true;

734}

735

739 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());

741

742 uint64_t N = Value.countr_zero();

744 return true;

745}

746

751 assert(Call->getArg(0)->isLValue());

752 PrimType PtrT = S.getContext().classify(Call->getArg(0)).value_or(PT_Ptr);

753

757 } else if (PtrT == PT_Ptr) {

759 S.Stk.push<Pointer>(Arg);

760 } else {

761 assert(false && "Unsupported pointer type passed to __builtin_addressof()");

762 }

763 return true;

764}

765

769

770 PrimType ArgT = S.getContext().classify(Call->getArg(0)).value_or(PT_Ptr);

771

772 TYPE_SWITCH(ArgT, const T &Arg = S.Stk.peek<T>(); S.Stk.push<T>(Arg););

773

774 return Func->getDecl()->isConstexpr();

775}

776

781 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());

783

785 Arg.getZExtValue());

787 return true;

788}

789

790

794 S.Stk.push<Pointer>(Arg);

795 return true;

796}

797

798

805 return false;

806

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);

817 bool Overflow;

818

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);

831

832

833

834

835

836 if (IsSigned && !AllSigned)

837 ++MaxBits;

838

839 LHS = APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);

840 RHS = APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);

842 }

843

844

845 switch (BuiltinOp) {

846 default:

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);

857 break;

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);

867 break;

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);

877 break;

878 }

879

880

881

882 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||

883 BuiltinOp == Builtin::BI__builtin_sub_overflow ||

884 BuiltinOp == Builtin::BI__builtin_mul_overflow) {

885

886

887

888

891

892 if (!APSInt::isSameValue(Temp, Result))

893 Overflow = true;

895 }

896

897

900 assert(Func->getDecl()->getReturnType()->isBooleanType());

901 S.Stk.push<Boolean>(Overflow);

902 return true;

903}

904

905

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());

924

926

928 CarryOut = LHS;

929

930 bool FirstOverflowed = false;

931 bool SecondOverflowed = false;

932 switch (BuiltinOp) {

933 default:

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);

942 break;

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);

950 break;

951 }

952

953

954 CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed);

955

957 QualType CarryOutType = Call->getArg(3)->getType()->getPointeeType();

958 PrimType CarryOutT = *S.getContext().classify(CarryOutType);

961

962 assert(Call->getType() == Call->getArg(0)->getType());

964 return true;

965}

966

971 unsigned BuiltinOp = Func->getBuiltinID();

972 PrimType ValT = *S.getContext().classify(Call->getArg(0));

974

975

976

977 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&

978 BuiltinOp != Builtin::BI__lzcnt &&

979 BuiltinOp != Builtin::BI__lzcnt64;

980

981 if (Val == 0) {

982 if (Func->getBuiltinID() == Builtin::BI__builtin_clzg &&

983 Call->getNumArgs() == 2) {

984

985 PrimType FallbackT = *S.getContext().classify(Call->getArg(1));

988 return true;

989 }

990

991 if (ZeroIsUndefined)

992 return false;

993 }

994

996 return true;

997}

998

1003 PrimType ValT = *S.getContext().classify(Call->getArg(0));

1005

1006 if (Val == 0) {

1007 if (Func->getBuiltinID() == Builtin::BI__builtin_ctzg &&

1008 Call->getNumArgs() == 2) {

1009

1010 PrimType FallbackT = *S.getContext().classify(Call->getArg(1));

1013 return true;

1014 }

1015 return false;

1016 }

1017

1019 return true;

1020}

1021

1025 PrimType ReturnT = *S.getContext().classify(Call->getType());

1026 PrimType ValT = *S.getContext().classify(Call->getArg(0));

1028 assert(Val.getActiveBits() <= 64);

1029

1031 { S.Stk.push<T>(T::from(Val.byteSwap().getZExtValue())); });

1032 return true;

1033}

1034

1035

1036

1037

1042 unsigned BuiltinOp = Func->getBuiltinID();

1043

1044 PrimType ValT = *S.getContext().classify(Call->getArg(0));

1045 unsigned SizeValOffset = 0;

1046 if (BuiltinOp != Builtin::BI__c11_atomic_is_lock_free)

1049

1050 auto returnBool = [&S](bool Value) -> bool {

1052 return true;

1053 };

1054

1055

1056

1057

1058

1059

1060

1061

1062

1063

1064

1066 if (Size.isPowerOfTwo()) {

1067

1068 unsigned InlineWidthBits =

1071

1072

1073

1074 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||

1076 return returnBool(true);

1077

1078

1079 assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);

1082 return returnBool(true);

1083

1086 if (APSInt(APInt(64, IntVal, false), true).isAligned(Size.getAsAlign()))

1087 return returnBool(true);

1088 }

1089

1090 const Expr *PtrArg = Call->getArg(1);

1091

1092 if (const auto *ICE = dyn_cast(PtrArg)) {

1093

1094

1095 if (ICE->getCastKind() == CK_BitCast)

1096 PtrArg = ICE->getSubExpr();

1097 }

1098

1103

1104 return returnBool(true);

1105 }

1106 }

1107 }

1108 }

1109

1110 if (BuiltinOp == Builtin::BI__atomic_always_lock_free)

1111 return returnBool(false);

1112

1113 return false;

1114}

1115

1116

1125

1127 Result.atIndex(0).initialize();

1129 Result.atIndex(1).initialize();

1130 Result.initialize();

1131

1132 return true;

1133}

1134

1135

1136

1137

1138

1139

1144 unsigned BuiltinOp = Func->getBuiltinID();

1146

1147 PrimType AlignmentT = *S.Ctx.classify(Call->getArg(1));

1149

1150 if (Alignment < 0 || !Alignment.isPowerOf2()) {

1151 S.FFDiag(Call, diag::note_constexpr_invalid_alignment) << Alignment;

1152 return false;

1153 }

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;

1159 return false;

1160 }

1161

1162

1163

1164 PrimType FirstArgT = *S.Ctx.classify(Call->getArg(0));

1165

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());

1176 } else {

1177 assert(*S.Ctx.classify(Call->getType()) == PT_Bool);

1178 S.Stk.push<Boolean>((Src & (Align - 1)) == 0);

1179 }

1180 return true;

1181 }

1182

1183 assert(FirstArgT == PT_Ptr);

1185

1192

1193 if (BuiltinOp == Builtin::BI__builtin_is_aligned) {

1194 if (PtrAlign.getQuantity() >= Alignment) {

1195 S.Stk.push<Boolean>(true);

1196 return true;

1197 }

1198

1199

1200

1201

1202 if (BaseAlignment.getQuantity() >= Alignment &&

1204 S.Stk.push<Boolean>(false);

1205 return true;

1206 }

1207

1208 S.FFDiag(Call->getArg(0), diag::note_constexpr_alignment_compute)

1209 << Alignment;

1210 return false;

1211 }

1212

1213 assert(BuiltinOp == Builtin::BI__builtin_align_down ||

1214 BuiltinOp == Builtin::BI__builtin_align_up);

1215

1216

1217

1218 if (PtrAlign.getQuantity() >= Alignment) {

1219 S.Stk.push<Pointer>(Ptr);

1220 return true;

1221 }

1222

1223

1224

1225

1226

1227

1228 if (BaseAlignment.getQuantity() >= Alignment) {

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));

1236

1238 return true;

1239 }

1240

1241

1242 S.FFDiag(Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;

1243 return false;

1244}

1245

1246

1251 assert(Call->getNumArgs() == 2 || Call->getNumArgs() == 3);

1252

1253

1254 std::optional PtrT = S.Ctx.classify(Call->getArg(0));

1256 return false;

1257

1260 std::optional ExtraOffset;

1262 if (Call->getNumArgs() == 2) {

1263 Alignment = peekToAPSInt(S.Stk, *S.Ctx.classify(Call->getArg(1)));

1264 } else {

1265 PrimType AlignmentT = *S.Ctx.classify(Call->getArg(1));

1266 PrimType ExtraOffsetT = *S.Ctx.classify(Call->getArg(2));

1267 Alignment = peekToAPSInt(S.Stk, *S.Ctx.classify(Call->getArg(1)),

1270 ExtraOffset = peekToAPSInt(S.Stk, *S.Ctx.classify(Call->getArg(2)));

1271 }

1272

1274

1275

1282

1283 if (BaseAlignment < Align) {

1284 S.CCEDiag(Call->getArg(0),

1285 diag::note_constexpr_baa_insufficient_alignment)

1287 return false;

1288 }

1289 }

1290

1293 if (ExtraOffset)

1295 if (AVOffset.alignTo(Align) != AVOffset) {

1297 S.CCEDiag(Call->getArg(0),

1298 diag::note_constexpr_baa_insufficient_alignment)

1300 else

1301 S.CCEDiag(Call->getArg(0),

1302 diag::note_constexpr_baa_value_insufficient_alignment)

1304 return false;

1305 }

1306

1307 S.Stk.push<Pointer>(Ptr);

1308 return true;

1309}

1310

1315 if (Call->getNumArgs() != 2 || Call->getArg(0)->getType()->isIntegerType() ||

1316 Call->getArg(1)->getType()->isIntegerType())

1317 return false;

1318

1319 PrimType ValT = *S.Ctx.classify(Call->getArg(0));

1320 PrimType IndexT = *S.Ctx.classify(Call->getArg(1));

1324

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;

1329

1330

1331 if (Length == 0 || Shift >= BitWidth) {

1333 return true;

1334 }

1335

1336 uint64_t Result = Val.getZExtValue() >> Shift;

1337 Result &= llvm::maskTrailingOnes<uint64_t>(Length);

1339 return true;

1340}

1341

1347 if (Call->getNumArgs() != 2 || Call->getArg(0)->getType()->isIntegerType() ||

1348 Call->getArg(1)->getType()->isIntegerType() ||

1350 return false;

1351

1352 PrimType ValT = *S.Ctx.classify(Call->getArg(0));

1353 PrimType IndexT = *S.Ctx.classify(Call->getArg(1));

1354

1358

1359 unsigned BitWidth = Val.getBitWidth();

1360 uint64_t Index = Idx.extractBitsAsZExtValue(8, 0);

1361

1362 if (Index < BitWidth)

1363 Val.clearHighBits(BitWidth - Index);

1364

1366 return true;

1367}

1368

1375 Call->getArg(0)->getType()->isIntegerType())

1376 return false;

1377

1379 pushInteger(S, Val.countLeadingZeros(), CallType);

1380 return true;

1381}

1382

1389 Call->getArg(0)->getType()->isIntegerType())

1390 return false;

1391

1393 pushInteger(S, Val.countTrailingZeros(), CallType);

1394 return true;

1395}

1396

1401 if (Call->getNumArgs() != 2 || Call->getArg(0)->getType()->isIntegerType() ||

1402 Call->getArg(1)->getType()->isIntegerType())

1403 return false;

1404

1405 PrimType ValT = *S.Ctx.classify(Call->getArg(0));

1406 PrimType MaskT = *S.Ctx.classify(Call->getArg(1));

1407

1411

1412 unsigned BitWidth = Val.getBitWidth();

1413 APInt Result = APInt::getZero(BitWidth);

1414 for (unsigned I = 0, P = 0; I != BitWidth; ++I) {

1415 if (Mask[I])

1416 Result.setBitVal(I, Val[P++]);

1417 }

1419 return true;

1420}

1421

1426 if (Call->getNumArgs() != 2 || Call->getArg(0)->getType()->isIntegerType() ||

1427 Call->getArg(1)->getType()->isIntegerType())

1428 return false;

1429

1430 PrimType ValT = *S.Ctx.classify(Call->getArg(0));

1431 PrimType MaskT = *S.Ctx.classify(Call->getArg(1));

1432

1436

1437 unsigned BitWidth = Val.getBitWidth();

1438 APInt Result = APInt::getZero(BitWidth);

1439 for (unsigned I = 0, P = 0; I != BitWidth; ++I) {

1440 if (Mask[I])

1441 Result.setBitVal(P++, Val[I]);

1442 }

1444 return true;

1445}

1446

1452 if (Call->getNumArgs() != 4 || Call->getArg(0)->getType()->isIntegerType() ||

1453 Call->getArg(1)->getType()->isIntegerType() ||

1454 Call->getArg(2)->getType()->isIntegerType())

1455 return false;

1456

1457 unsigned BuiltinOp = Func->getBuiltinID();

1461

1462 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||

1463 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;

1464

1465 unsigned BitWidth = LHS.getBitWidth();

1466 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;

1467 APInt ExResult =

1468 IsAdd ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))

1469 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));

1470

1471 APInt Result = ExResult.extractBits(BitWidth, 0);

1473 APSInt(ExResult.extractBits(1, BitWidth), true);

1474

1476 QualType CarryOutType = Call->getArg(3)->getType()->getPointeeType();

1477 PrimType CarryOutT = *S.getContext().classify(CarryOutType);

1479

1481

1482 return true;

1483}

1484

1493 return true;

1494}

1495

1499 const auto &Ptr = S.Stk.peek<Pointer>();

1500 assert(Ptr.getFieldDesc()->isPrimitiveArray());

1501

1502 StringRef R(&Ptr.deref<char>(), Ptr.getFieldDesc()->getNumElems() - 1);

1503 uint64_t Result = getPointerAuthStableSipHash(R);

1505 return true;

1506}

1507

1508

1509

1510

1511

1516 const Expr *Arg = Call->getArg(0);

1518

1519 auto returnInt = [&S, Call](bool Value) -> bool {

1521 return true;

1522 };

1523

1524

1525

1526

1527

1528

1529

1530

1531

1532

1533

1534

1535

1536

1537

1543 auto Res = C.interpretExpr(Arg, Arg->isGLValue());

1544 if (Res.isInvalid()) {

1545 C.cleanup();

1547 return returnInt(false);

1548 }

1549

1550 if (!Res.empty()) {

1551 const APValue &LV = Res.toAPValue();

1554 if (Base.isNull()) {

1555

1556 return returnInt(true);

1557 } else if (const auto *E = Base.dyn_cast<const Expr *>()) {

1558 if (!isa(E))

1559 return returnInt(false);

1562

1563

1564 return returnInt(true);

1565 } else {

1566

1567 return returnInt(false);

1568 }

1569 }

1570 }

1571

1572

1573 return returnInt(true);

1574 }

1575

1576 return returnInt(false);

1577}

1578

1583

1584

1585

1587

1591 continue;

1592 const auto *MD = dyn_cast_if_present(Func->getDecl());

1593 if (!MD)

1594 continue;

1596 if (!FnII || !FnII->isStr("allocate"))

1597 continue;

1598

1599 const auto *CTSD =

1600 dyn_cast(MD->getParent());

1601 if (!CTSD)

1602 continue;

1603

1604 const IdentifierInfo *ClassII = CTSD->getIdentifier();

1606 if (CTSD->isInStdNamespace() && ClassII && ClassII->isStr("allocator") &&

1608 ElemType = TAL[0].getAsType();

1609 break;

1610 }

1611 }

1612

1613 if (ElemType.isNull()) {

1615 ? diag::note_constexpr_new_untyped

1616 : diag::note_constexpr_new);

1617 return false;

1618 }

1619

1621 S.FFDiag(Call, diag::note_constexpr_new_not_complete_object_type)

1623 return false;

1624 }

1625

1628 assert(!ElemSize.isZero());

1629

1630

1631 APInt NumElems, Remainder;

1633 APInt::udivrem(Bytes, ElemSizeAP, NumElems, Remainder);

1634 if (Remainder != 0) {

1635

1636 S.FFDiag(Call, diag::note_constexpr_operator_new_bad_size)

1637 << Bytes << APSInt(ElemSizeAP, true) << ElemType;

1638 return false;

1639 }

1640

1641

1642 if (NumElems.getActiveBits() >

1645

1646 const SourceInfo &Loc = S.Current->getSource(OpPC);

1647 S.FFDiag(Loc, diag::note_constexpr_new_too_large)

1648 << NumElems.getZExtValue();

1649 return false;

1650 }

1651

1652 std::optional ElemT = S.getContext().classify(ElemType);

1654 if (ElemT) {

1655 if (NumElems.ule(1)) {

1658 false, false,

1659 false);

1660 Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),

1662 assert(B);

1663

1665 return true;

1666 }

1667 assert(NumElems.ugt(1));

1668

1670 Allocator.allocate(Call, *ElemT, NumElems.getZExtValue(),

1672 assert(B);

1674 return true;

1675 }

1676

1677 assert(!ElemT);

1678

1679 const Descriptor *Desc = S.P.createDescriptor(

1681 false, false, false,

1682 nullptr);

1683

1684 if (NumElems.ule(1)) {

1685 Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),

1687 assert(B);

1689 return true;

1690 }

1691

1693 Allocator.allocate(Desc, NumElems.getZExtValue(), S.Ctx.getEvalID(),

1695 assert(B);

1697 return true;

1698}

1699

1704 const Expr *Source = nullptr;

1705 const Block *BlockToDelete = nullptr;

1706

1707 {

1709

1711 S.CCEDiag(Call, diag::note_constexpr_deallocate_null);

1712 return true;

1713 }

1714

1716 BlockToDelete = Ptr.block();

1717 }

1718 assert(BlockToDelete);

1719

1722 std::optionalDynamicAllocator::Form AllocForm =

1723 Allocator.getAllocationForm(Source);

1724

1725 if (!Allocator.deallocate(Source, BlockToDelete, S)) {

1726

1727 const SourceInfo &Loc = S.Current->getSource(OpPC);

1728 S.FFDiag(Loc, diag::note_constexpr_double_delete);

1729 return false;

1730 }

1731 assert(AllocForm);

1732

1735}

1736

1743 return true;

1744}

1745

1752

1753 unsigned ID = Func->getBuiltinID();

1755 assert(Call->getType() == ElemType);

1756 PrimType ElemT = *S.getContext().classify(ElemType);

1758

1761 unsigned BitWidth = Result.bitWidth();

1762 for (unsigned I = 1; I != NumElems; ++I) {

1763 T Elem = Arg.atIndex(I).deref();

1765

1766 if (ID == Builtin::BI__builtin_reduce_add) {

1767 if (T::add(Result, Elem, BitWidth, &Result)) {

1768 unsigned OverflowBits = BitWidth + 1;

1770 (PrevResult.toAPSInt(OverflowBits) +

1771 Elem.toAPSInt(OverflowBits)));

1772 return false;

1773 }

1774 } else if (ID == Builtin::BI__builtin_reduce_mul) {

1775 if (T::mul(Result, Elem, BitWidth, &Result)) {

1776 unsigned OverflowBits = BitWidth * 2;

1778 (PrevResult.toAPSInt(OverflowBits) *

1779 Elem.toAPSInt(OverflowBits)));

1780 return false;

1781 }

1782

1783 } else if (ID == Builtin::BI__builtin_reduce_and) {

1784 (void)T::bitAnd(Result, Elem, BitWidth, &Result);

1785 } else if (ID == Builtin::BI__builtin_reduce_or) {

1786 (void)T::bitOr(Result, Elem, BitWidth, &Result);

1787 } else if (ID == Builtin::BI__builtin_reduce_xor) {

1788 (void)T::bitXor(Result, Elem, BitWidth, &Result);

1789 } else {

1790 llvm_unreachable("Unhandled vector reduce builtin");

1791 }

1792 }

1794 });

1795

1796 return true;

1797}

1798

1799

1804 assert(Call->getNumArgs() == 1);

1805 if (Call->getArg(0)->getType()->isIntegerType()) {

1806 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());

1809 return true;

1810 }

1811

1812 assert(Call->getArg(0)->getType()->isVectorType());

1819

1821 PrimType ElemT = *S.getContext().classify(ElemType);

1823

1824

1825 for (unsigned I = 0; I != NumElems; ++I) {

1827 Dst.atIndex(I).deref() =

1828 T::from(Arg.atIndex(I).deref<T>().toAPSInt().popcount());

1830 });

1831 }

1832

1833 return true;

1834}

1835

1839 assert(Call->getNumArgs() == 3);

1840 unsigned ID = Func->getBuiltinID();

1841 Pointer DestPtr = getParam(Frame, 0);

1843 const Pointer &SrcPtr = getParam(Frame, 1);

1844 const APSInt &Size =

1845 peekToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2)));

1846 assert(!Size.isSigned() && "memcpy and friends take an unsigned size");

1847

1848 if (ID == Builtin::BImemcpy || ID == Builtin::BImemmove)

1850

1851 bool Move = (ID == Builtin::BI__builtin_memmove || ID == Builtin::BImemmove);

1852

1853

1854 if (Size.isZero()) {

1855 S.Stk.push<Pointer>(DestPtr);

1856 return true;

1857 }

1858

1860 Pointer DiagPtr = (SrcPtr.isZero() ? SrcPtr : DestPtr);

1861 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_null)

1862 << Move << false << !SrcPtr.isZero()

1864 return false;

1865 }

1866

1867

1869 return false;

1870

1872 size_t RemainingDestElems;

1876 ? 0

1878 } else {

1879 DestElemType = DestPtr.getType();

1880 RemainingDestElems = 1;

1881 }

1883

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

1888 << DestElemSize;

1889 return false;

1890 }

1891

1893 size_t RemainingSrcElems;

1897 ? 0

1899 } else {

1900 SrcElemType = SrcPtr.getType();

1901 RemainingSrcElems = 1;

1902 }

1904

1906 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_type_pun)

1907 << Move << SrcElemType << DestElemType;

1908 return false;

1909 }

1910

1911

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);

1920 return false;

1921 }

1922

1923

1926 unsigned DstIndex = DestPtr.getIndex() * DestPtr.elemSize();

1927 unsigned N = Size.getZExtValue();

1928

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)

1932 << false;

1933 return false;

1934 }

1935 }

1936

1937 assert(Size.getZExtValue() % DestElemSize == 0);

1938 if (DoMemcpy(S, OpPC, SrcPtr, DestPtr, Bytes(Size.getZExtValue()).toBits()))

1939 return false;

1940

1941 S.Stk.push<Pointer>(DestPtr);

1942 return true;

1943}

1944

1945

1946

1949}

1950

1954 assert(Call->getNumArgs() == 3);

1955 unsigned ID = Func->getBuiltinID();

1956 const Pointer &PtrA = getParam(Frame, 0);

1957 const Pointer &PtrB = getParam(Frame, 1);

1958 const APSInt &Size =

1959 peekToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2)));

1960

1961 if (ID == Builtin::BImemcmp || ID == Builtin::BIbcmp ||

1962 ID == Builtin::BIwmemcmp)

1964

1965 if (Size.isZero()) {

1967 return true;

1968 }

1969

1970 bool IsWide =

1971 (ID == Builtin::BIwmemcmp || ID == Builtin::BI__builtin_wmemcmp);

1972

1974

1975

1978 S.FFDiag(S.Current->getSource(OpPC),

1979 diag::note_constexpr_memcmp_unsupported)

1982 return false;

1983 }

1984

1986 return false;

1987

1988

1992

1993

1996

2000

2001

2004

2007

2008 unsigned ElemSize = 1;

2009 if (IsWide)

2011

2012

2013 size_t ByteSize = Size.getZExtValue() * ElemSize;

2014 size_t CmpSize = std::min(MinBufferSize, ByteSize);

2015

2016 for (size_t I = 0; I != CmpSize; I += ElemSize) {

2017 if (IsWide) {

2019 T A = *reinterpret_cast<T *>(BufferA.Data.get() + I);

2020 T B = *reinterpret_cast<T *>(BufferB.Data.get() + I);

2021 if (A < B) {

2022 pushInteger(S, -1, Call->getType());

2023 return true;

2024 } else if (A > B) {

2026 return true;

2027 }

2028 });

2029 } else {

2030 std::byte A = BufferA.Data[I];

2031 std::byte B = BufferB.Data[I];

2032

2033 if (A < B) {

2035 return true;

2036 } else if (A > B) {

2038 return true;

2039 }

2040 }

2041 }

2042

2043

2044

2045 if (ByteSize <= CmpSize) {

2047 return true;

2048 }

2049

2050

2051

2052

2053

2054 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_past_end)

2055 << AK_Read << S.Current->getRange(OpPC);

2056 return false;

2057}

2058

2062

2063 std::optional ReturnT = S.getContext().classify(Call);

2064

2065 switch (BuiltinID) {

2066 case Builtin::BI__builtin_is_constant_evaluated:

2068 return false;

2069 break;

2070 case Builtin::BI__builtin_assume:

2071 case Builtin::BI__assume:

2072 break;

2073 case Builtin::BI__builtin_strcmp:

2074 case Builtin::BIstrcmp:

2075 case Builtin::BI__builtin_strncmp:

2076 case Builtin::BIstrncmp:

2078 return false;

2079 break;

2080 case Builtin::BI__builtin_strlen:

2081 case Builtin::BIstrlen:

2082 case Builtin::BI__builtin_wcslen:

2083 case Builtin::BIwcslen:

2085 return false;

2086 break;

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:

2093 return false;

2094 break;

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:

2101 return false;

2102 break;

2103

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:

2115 return false;

2116 break;

2117 case Builtin::BI__builtin_copysign:

2118 case Builtin::BI__builtin_copysignf:

2119 case Builtin::BI__builtin_copysignl:

2120 case Builtin::BI__builtin_copysignf128:

2122 return false;

2123 break;

2124

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:

2131 return false;

2132 break;

2133

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:

2140 return false;

2141 break;

2142

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:

2149 return false;

2150 break;

2151

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:

2158 return false;

2159 break;

2160

2161 case Builtin::BI__builtin_isnan:

2163 return false;

2164 break;

2165 case Builtin::BI__builtin_issignaling:

2167 return false;

2168 break;

2169

2170 case Builtin::BI__builtin_isinf:

2172 return false;

2173 break;

2174

2175 case Builtin::BI__builtin_isinf_sign:

2177 return false;

2178 break;

2179

2180 case Builtin::BI__builtin_isfinite:

2182 return false;

2183 break;

2184 case Builtin::BI__builtin_isnormal:

2186 return false;

2187 break;

2188 case Builtin::BI__builtin_issubnormal:

2190 return false;

2191 break;

2192 case Builtin::BI__builtin_iszero:

2194 return false;

2195 break;

2196 case Builtin::BI__builtin_signbit:

2197 case Builtin::BI__builtin_signbitf:

2198 case Builtin::BI__builtin_signbitl:

2200 return false;

2201 break;

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:

2209 return false;

2210 break;

2211 case Builtin::BI__builtin_isfpclass:

2213 return false;

2214 break;

2215 case Builtin::BI__builtin_fpclassify:

2217 return false;

2218 break;

2219

2220 case Builtin::BI__builtin_fabs:

2221 case Builtin::BI__builtin_fabsf:

2222 case Builtin::BI__builtin_fabsl:

2223 case Builtin::BI__builtin_fabsf128:

2225 return false;

2226 break;

2227

2228 case Builtin::BI__builtin_abs:

2229 case Builtin::BI__builtin_labs:

2230 case Builtin::BI__builtin_llabs:

2232 return false;

2233 break;

2234

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:

2243 return false;

2244 break;

2245

2246 case Builtin::BI__builtin_parity:

2247 case Builtin::BI__builtin_parityl:

2248 case Builtin::BI__builtin_parityll:

2250 return false;

2251 break;

2252

2253 case Builtin::BI__builtin_clrsb:

2254 case Builtin::BI__builtin_clrsbl:

2255 case Builtin::BI__builtin_clrsbll:

2257 return false;

2258 break;

2259

2260 case Builtin::BI__builtin_bitreverse8:

2261 case Builtin::BI__builtin_bitreverse16:

2262 case Builtin::BI__builtin_bitreverse32:

2263 case Builtin::BI__builtin_bitreverse64:

2265 return false;

2266 break;

2267

2268 case Builtin::BI__builtin_classify_type:

2270 return false;

2271 break;

2272

2273 case Builtin::BI__builtin_expect:

2274 case Builtin::BI__builtin_expect_with_probability:

2276 return false;

2277 break;

2278

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:

2289 return false;

2290 break;

2291

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:

2302 return false;

2303 break;

2304

2305 case Builtin::BI__builtin_ffs:

2306 case Builtin::BI__builtin_ffsl:

2307 case Builtin::BI__builtin_ffsll:

2309 return false;

2310 break;

2311 case Builtin::BIaddressof:

2312 case Builtin::BI__addressof:

2313 case Builtin::BI__builtin_addressof:

2315 return false;

2316 break;

2317

2318 case Builtin::BIas_const:

2319 case Builtin::BIforward:

2320 case Builtin::BIforward_like:

2321 case Builtin::BImove:

2322 case Builtin::BImove_if_noexcept:

2324 return false;

2325 break;

2326

2327 case Builtin::BI__builtin_eh_return_data_regno:

2329 return false;

2330 break;

2331

2332 case Builtin::BI__builtin_launder:

2334 return false;

2335 break;

2336

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:

2359 return false;

2360 break;

2361

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:

2373 return false;

2374 break;

2375

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:

2385 return false;

2386 break;

2387

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:

2394 return false;

2395 break;

2396

2397 case Builtin::BI__builtin_bswap16:

2398 case Builtin::BI__builtin_bswap32:

2399 case Builtin::BI__builtin_bswap64:

2401 return false;

2402 break;

2403

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:

2408 return false;

2409 break;

2410

2411 case Builtin::BI__builtin_complex:

2413 return false;

2414 break;

2415

2416 case Builtin::BI__builtin_is_aligned:

2417 case Builtin::BI__builtin_align_up:

2418 case Builtin::BI__builtin_align_down:

2420 return false;

2421 break;

2422

2423 case Builtin::BI__builtin_assume_aligned:

2425 return false;

2426 break;

2427

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:

2433 return false;

2434 break;

2435

2436 case clang::X86::BI__builtin_ia32_bzhi_si:

2437 case clang::X86::BI__builtin_ia32_bzhi_di:

2439 return false;

2440 break;

2441

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:

2446 return false;

2447 break;

2448

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:

2453 return false;

2454 break;

2455

2456 case clang::X86::BI__builtin_ia32_pdep_si:

2457 case clang::X86::BI__builtin_ia32_pdep_di:

2459 return false;

2460 break;

2461

2462 case clang::X86::BI__builtin_ia32_pext_si:

2463 case clang::X86::BI__builtin_ia32_pext_di:

2465 return false;

2466 break;

2467

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:

2473 return false;

2474 break;

2475

2476 case Builtin::BI__builtin_os_log_format_buffer_size:

2478 return false;

2479 break;

2480

2481 case Builtin::BI__builtin_ptrauth_string_discriminator:

2483 return false;

2484 break;

2485

2486 case Builtin::BI__builtin_constant_p:

2488 return false;

2489 break;

2490

2491 case Builtin::BI__noop:

2493 break;

2494

2495 case Builtin::BI__builtin_operator_new:

2497 return false;

2498 break;

2499

2500 case Builtin::BI__builtin_operator_delete:

2502 return false;

2503 break;

2504

2505 case Builtin::BI__arithmetic_fence:

2507 return false;

2508 break;

2509

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:

2516 return false;

2517 break;

2518

2519 case Builtin::BI__builtin_elementwise_popcount:

2521 return false;

2522 break;

2523

2524 case Builtin::BI__builtin_memcpy:

2525 case Builtin::BImemcpy:

2526 case Builtin::BI__builtin_memmove:

2527 case Builtin::BImemmove:

2529 return false;

2530 break;

2531

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:

2539 return false;

2540 break;

2541

2542 default:

2543 S.FFDiag(S.Current->getLocation(OpPC),

2544 diag::note_invalid_subexpr_in_const_expr)

2545 << S.Current->getRange(OpPC);

2546

2547 return false;

2548 }

2549

2551}

2552

2555 int64_t &IntResult) {

2557 unsigned N = E->getNumComponents();

2558 assert(N > 0);

2559

2560 unsigned ArrayIndex = 0;

2562 for (unsigned I = 0; I != N; ++I) {

2564 switch (Node.getKind()) {

2568 if (!RT)

2569 return false;

2572 return false;

2574 unsigned FieldIndex = MemberDecl->getFieldIndex();

2575 assert(FieldIndex < RL.getFieldCount() && "offsetof field in wrong type");

2579 break;

2580 }

2582

2583

2584 int64_t Index = ArrayIndices[ArrayIndex];

2586 if (!AT)

2587 return false;

2590 Result += Index * ElementSize;

2591 ++ArrayIndex;

2592 break;

2593 }

2597 return false;

2598

2599

2601 if (!RT)

2602 return false;

2605 return false;

2607

2608

2609 CurrentType = BaseSpec->getType();

2611 if (!BaseRT)

2612 return false;

2613

2614

2616 break;

2617 }

2619 llvm_unreachable("Dependent OffsetOfExpr?");

2620 }

2621 }

2622

2623 IntResult = Result.getQuantity();

2624

2625 return true;

2626}

2627

2630

2632 assert(R);

2634

2637 PrimType FieldT = *S.getContext().classify(FieldPtr.getType());

2638

2640 FieldPtr.deref<T>() = T::from(IntValue.getSExtValue()));

2642 return true;

2643}

2644

2645static bool copyComposite(InterpState &S, CodePtr OpPC, const Pointer &Src,

2646 Pointer &Dest, bool Activate);

2648 Pointer &Dest, bool Activate = false) {

2651

2652 auto copyField = [&](const Record::Field &F, bool Activate) -> bool {

2654 if (std::optional FT = S.Ctx.classify(F.Decl->getType())) {

2659 if (Activate)

2661 });

2662 return true;

2663 }

2664

2666 };

2667

2668 assert(SrcDesc->isRecord());

2671 for (const Record::Field &F : R->fields()) {

2673

2676 if (!copyField(F, true))

2677 return false;

2678 }

2679 } else {

2680 if (!copyField(F, Activate))

2681 return false;

2682 }

2683 }

2684

2685 for (const Record::Base &B : R->bases()) {

2687 if (!copyRecord(S, OpPC, Src.atField(B.Offset), DestBase, Activate))

2688 return false;

2689 }

2690

2692 return true;

2693}

2694

2696 Pointer &Dest, bool Activate = false) {

2698

2701

2703

2708 for (unsigned I = 0, N = DestDesc->getNumElems(); I != N; ++I) {

2713 });

2714 }

2715 return true;

2716 }

2717

2719 return copyRecord(S, OpPC, Src, Dest, Activate);

2720 return Invalid(S, OpPC);

2721}

2722

2725}

2726

2727}

2728}

Defines enum values for all the target-independent builtin functions.

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'.

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.