Lines Matching defs:S
43 bool ReturnValue(const InterpState &S, const T &V, APValue &R) {
44 R = V.toAPValue(S.getCtx());
49 bool CheckExtern(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
52 bool CheckArray(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
55 bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
59 bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
63 bool CheckNull(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
67 bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
71 bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
75 bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
80 bool CheckDowncast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
84 bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
87 bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc);
90 bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
93 bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
96 bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
99 bool CheckGlobalInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
102 bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
105 bool CheckInvoke(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
108 bool CheckInit(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
111 bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F);
115 bool CheckCallDepth(InterpState &S, CodePtr OpPC);
118 bool CheckThis(InterpState &S, CodePtr OpPC, const Pointer &This);
121 bool CheckPure(InterpState &S, CodePtr OpPC, const CXXMethodDecl *MD);
124 bool CheckNonNullArgs(InterpState &S, CodePtr OpPC, const Function *F,
129 bool CheckDynamicMemoryAllocation(InterpState &S, CodePtr OpPC);
132 bool CheckNewDeleteForms(InterpState &S, CodePtr OpPC, bool NewWasArray,
138 bool CheckDeleteSource(InterpState &S, CodePtr OpPC, const Expr *Source,
143 bool SetThreeWayComparisonField(InterpState &S, CodePtr OpPC,
147 bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest);
151 bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS,
154 const SourceInfo &Loc = S.Current->getSource(OpPC);
155 S.CCEDiag(Loc, diag::note_constexpr_negative_shift) << RHS.toAPSInt();
156 if (!S.noteUndefinedBehavior())
163 const Expr *E = S.Current->getExpr(OpPC);
166 S.CCEDiag(E, diag::note_constexpr_large_shift) << Val << Ty << Bits;
167 if (!S.noteUndefinedBehavior())
171 if (LHS.isSigned() && !S.getLangOpts().CPlusPlus20) {
172 const Expr *E = S.Current->getExpr(OpPC);
176 S.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS.toAPSInt();
177 if (!S.noteUndefinedBehavior())
181 S.CCEDiag(E, diag::note_constexpr_lshift_discards);
182 if (!S.noteUndefinedBehavior())
195 bool CheckDivRem(InterpState &S, CodePtr OpPC, const T &LHS, const T &RHS) {
197 const auto *Op = cast<BinaryOperator>(S.Current->getExpr(OpPC));
199 S.CCEDiag(Op, diag::note_expr_divide_by_zero)
204 S.FFDiag(Op, diag::note_expr_divide_by_zero)
213 const SourceInfo &Loc = S.Current->getSource(OpPC);
214 const Expr *E = S.Current->getExpr(OpPC);
215 S.CCEDiag(Loc, diag::note_constexpr_overflow) << Trunc << E->getType();
222 bool CheckArraySize(InterpState &S, CodePtr OpPC, SizeT *NumElements,
233 ConstantArrayType::getMaxSizeBits(S.getCtx()) ||
236 const SourceInfo &Loc = S.Current->getSource(OpPC);
237 S.FFDiag(Loc, diag::note_constexpr_new_too_large)
238 << NumElements->toDiagnosticString(S.getCtx());
247 bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result,
251 bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR);
254 bool Interpret(InterpState &S, APValue &Result);
257 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
261 bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
264 inline bool Invalid(InterpState &S, CodePtr OpPC);
272 void cleanupAfterFunctionCall(InterpState &S, CodePtr OpPC);
275 bool Ret(InterpState &S, CodePtr &PC, APValue &Result) {
276 const T &Ret = S.Stk.pop<T>();
290 assert(S.Current);
291 assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
292 if (!S.checkingPotentialConstantExpression() || S.Current->Caller)
293 cleanupAfterFunctionCall(S, PC);
295 if (InterpFrame *Caller = S.Current->Caller) {
296 PC = S.Current->getRetPC();
297 delete S.Current;
298 S.Current = Caller;
299 S.Stk.push<T>(Ret);
301 delete S.Current;
302 S.Current = nullptr;
303 if (!ReturnValue<T>(S, Ret, Result))
309 inline bool RetVoid(InterpState &S, CodePtr &PC, APValue &Result) {
310 assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
312 if (!S.checkingPotentialConstantExpression() || S.Current->Caller)
313 cleanupAfterFunctionCall(S, PC);
315 if (InterpFrame *Caller = S.Current->Caller) {
316 PC = S.Current->getRetPC();
317 delete S.Current;
318 S.Current = Caller;
320 delete S.Current;
321 S.Current = nullptr;
332 bool AddSubMulHelper(InterpState &S, CodePtr OpPC, unsigned Bits, const T &LHS,
337 S.Stk.push<T>(Result);
342 S.Stk.push<T>(Result);
348 const Expr *E = S.Current->getExpr(OpPC);
350 if (S.checkingForUndefinedBehavior()) {
356 S.report(Loc, diag::warn_integer_constant_overflow)
360 S.CCEDiag(E, diag::note_constexpr_overflow) << Value << Type;
362 if (!S.noteUndefinedBehavior()) {
363 S.Stk.pop<T>();
371 bool Add(InterpState &S, CodePtr OpPC) {
372 const T &RHS = S.Stk.pop<T>();
373 const T &LHS = S.Stk.pop<T>();
375 return AddSubMulHelper<T, T::add, std::plus>(S, OpPC, Bits, LHS, RHS);
378 inline bool Addf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) {
379 const Floating &RHS = S.Stk.pop<Floating>();
380 const Floating &LHS = S.Stk.pop<Floating>();
384 S.Stk.push<Floating>(Result);
385 return CheckFloatResult(S, OpPC, Result, Status);
389 bool Sub(InterpState &S, CodePtr OpPC) {
390 const T &RHS = S.Stk.pop<T>();
391 const T &LHS = S.Stk.pop<T>();
393 return AddSubMulHelper<T, T::sub, std::minus>(S, OpPC, Bits, LHS, RHS);
396 inline bool Subf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) {
397 const Floating &RHS = S.Stk.pop<Floating>();
398 const Floating &LHS = S.Stk.pop<Floating>();
402 S.Stk.push<Floating>(Result);
403 return CheckFloatResult(S, OpPC, Result, Status);
407 bool Mul(InterpState &S, CodePtr OpPC) {
408 const T &RHS = S.Stk.pop<T>();
409 const T &LHS = S.Stk.pop<T>();
411 return AddSubMulHelper<T, T::mul, std::multiplies>(S, OpPC, Bits, LHS, RHS);
414 inline bool Mulf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) {
415 const Floating &RHS = S.Stk.pop<Floating>();
416 const Floating &LHS = S.Stk.pop<Floating>();
420 S.Stk.push<Floating>(Result);
421 return CheckFloatResult(S, OpPC, Result, Status);
425 inline bool Mulc(InterpState &S, CodePtr OpPC) {
426 const Pointer &RHS = S.Stk.pop<Pointer>();
427 const Pointer &LHS = S.Stk.pop<Pointer>();
428 const Pointer &Result = S.Stk.peek<Pointer>();
480 inline bool Divc(InterpState &S, CodePtr OpPC) {
481 const Pointer &RHS = S.Stk.pop<Pointer>();
482 const Pointer &LHS = S.Stk.pop<Pointer>();
483 const Pointer &Result = S.Stk.peek<Pointer>();
512 const SourceInfo &E = S.Current->getSource(OpPC);
513 S.FFDiag(E, diag::note_expr_divide_by_zero);
555 bool BitAnd(InterpState &S, CodePtr OpPC) {
556 const T &RHS = S.Stk.pop<T>();
557 const T &LHS = S.Stk.pop<T>();
562 S.Stk.push<T>(Result);
572 bool BitOr(InterpState &S, CodePtr OpPC) {
573 const T &RHS = S.Stk.pop<T>();
574 const T &LHS = S.Stk.pop<T>();
579 S.Stk.push<T>(Result);
589 bool BitXor(InterpState &S, CodePtr OpPC) {
590 const T &RHS = S.Stk.pop<T>();
591 const T &LHS = S.Stk.pop<T>();
596 S.Stk.push<T>(Result);
606 bool Rem(InterpState &S, CodePtr OpPC) {
607 const T &RHS = S.Stk.pop<T>();
608 const T &LHS = S.Stk.pop<T>();
610 if (!CheckDivRem(S, OpPC, LHS, RHS))
616 S.Stk.push<T>(Result);
626 bool Div(InterpState &S, CodePtr OpPC) {
627 const T &RHS = S.Stk.pop<T>();
628 const T &LHS = S.Stk.pop<T>();
630 if (!CheckDivRem(S, OpPC, LHS, RHS))
636 S.Stk.push<T>(Result);
642 inline bool Divf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) {
643 const Floating &RHS = S.Stk.pop<Floating>();
644 const Floating &LHS = S.Stk.pop<Floating>();
646 if (!CheckDivRem(S, OpPC, LHS, RHS))
651 S.Stk.push<Floating>(Result);
652 return CheckFloatResult(S, OpPC, Result, Status);
660 bool Inv(InterpState &S, CodePtr OpPC) {
662 const T &Val = S.Stk.pop<T>();
667 S.Stk.push<BoolT>(R);
676 bool Neg(InterpState &S, CodePtr OpPC) {
677 const T &Value = S.Stk.pop<T>();
681 S.Stk.push<T>(Result);
687 S.Stk.push<T>(Result);
690 const Expr *E = S.Current->getExpr(OpPC);
693 if (S.checkingForUndefinedBehavior()) {
699 S.report(Loc, diag::warn_integer_constant_overflow)
704 S.CCEDiag(E, diag::note_constexpr_overflow) << NegatedValue << Type;
705 return S.noteUndefinedBehavior();
718 bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
722 if (!S.getLangOpts().CPlusPlus14)
723 return Invalid(S, OpPC);
730 S.Stk.push<T>(Value);
754 const Expr *E = S.Current->getExpr(OpPC);
756 if (S.checkingForUndefinedBehavior()) {
762 S.report(Loc, diag::warn_integer_constant_overflow)
767 S.CCEDiag(E, diag::note_constexpr_overflow) << APResult << Type;
768 return S.noteUndefinedBehavior();
776 bool Inc(InterpState &S, CodePtr OpPC) {
777 const Pointer &Ptr = S.Stk.pop<Pointer>();
778 if (!CheckLoad(S, OpPC, Ptr, AK_Increment))
781 return IncDecHelper<T, IncDecOp::Inc, PushVal::Yes>(S, OpPC, Ptr);
788 bool IncPop(InterpState &S, CodePtr OpPC) {
789 const Pointer &Ptr = S.Stk.pop<Pointer>();
790 if (!CheckLoad(S, OpPC, Ptr, AK_Increment))
793 return IncDecHelper<T, IncDecOp::Inc, PushVal::No>(S, OpPC, Ptr);
801 bool Dec(InterpState &S, CodePtr OpPC) {
802 const Pointer &Ptr = S.Stk.pop<Pointer>();
803 if (!CheckLoad(S, OpPC, Ptr, AK_Decrement))
806 return IncDecHelper<T, IncDecOp::Dec, PushVal::Yes>(S, OpPC, Ptr);
813 bool DecPop(InterpState &S, CodePtr OpPC) {
814 const Pointer &Ptr = S.Stk.pop<Pointer>();
815 if (!CheckLoad(S, OpPC, Ptr, AK_Decrement))
818 return IncDecHelper<T, IncDecOp::Dec, PushVal::No>(S, OpPC, Ptr);
822 bool IncDecFloatHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
828 S.Stk.push<Floating>(Value);
838 return CheckFloatResult(S, OpPC, Result, Status);
841 inline bool Incf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) {
842 const Pointer &Ptr = S.Stk.pop<Pointer>();
843 if (!CheckLoad(S, OpPC, Ptr, AK_Increment))
846 return IncDecFloatHelper<IncDecOp::Inc, PushVal::Yes>(S, OpPC, Ptr, RM);
849 inline bool IncfPop(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) {
850 const Pointer &Ptr = S.Stk.pop<Pointer>();
851 if (!CheckLoad(S, OpPC, Ptr, AK_Increment))
854 return IncDecFloatHelper<IncDecOp::Inc, PushVal::No>(S, OpPC, Ptr, RM);
857 inline bool Decf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) {
858 const Pointer &Ptr = S.Stk.pop<Pointer>();
859 if (!CheckLoad(S, OpPC, Ptr, AK_Decrement))
862 return IncDecFloatHelper<IncDecOp::Dec, PushVal::Yes>(S, OpPC, Ptr, RM);
865 inline bool DecfPop(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) {
866 const Pointer &Ptr = S.Stk.pop<Pointer>();
867 if (!CheckLoad(S, OpPC, Ptr, AK_Decrement))
870 return IncDecFloatHelper<IncDecOp::Dec, PushVal::No>(S, OpPC, Ptr, RM);
876 bool Comp(InterpState &S, CodePtr OpPC) {
877 const T &Val = S.Stk.pop<T>();
880 S.Stk.push<T>(Result);
894 bool CmpHelper(InterpState &S, CodePtr OpPC, CompareFn Fn) {
899 const T &RHS = S.Stk.pop<T>();
900 const T &LHS = S.Stk.pop<T>();
901 S.Stk.push<BoolT>(BoolT::from(Fn(LHS.compare(RHS))));
906 bool CmpHelperEQ(InterpState &S, CodePtr OpPC, CompareFn Fn) {
907 return CmpHelper<T>(S, OpPC, Fn);
912 inline bool CmpHelper<FunctionPointer>(InterpState &S, CodePtr OpPC,
914 const auto &RHS = S.Stk.pop<FunctionPointer>();
915 const auto &LHS = S.Stk.pop<FunctionPointer>();
917 const SourceInfo &Loc = S.Current->getSource(OpPC);
918 S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_unspecified)
919 << LHS.toDiagnosticString(S.getCtx())
920 << RHS.toDiagnosticString(S.getCtx());
925 inline bool CmpHelperEQ<FunctionPointer>(InterpState &S, CodePtr OpPC,
927 const auto &RHS = S.Stk.pop<FunctionPointer>();
928 const auto &LHS = S.Stk.pop<FunctionPointer>();
933 const SourceInfo &Loc = S.Current->getSource(OpPC);
934 S.FFDiag(Loc, diag::note_constexpr_pointer_weak_comparison)
935 << FP.toDiagnosticString(S.getCtx());
940 S.Stk.push<Boolean>(Boolean::from(Fn(LHS.compare(RHS))));
945 inline bool CmpHelper<Pointer>(InterpState &S, CodePtr OpPC, CompareFn Fn) {
947 const Pointer &RHS = S.Stk.pop<Pointer>();
948 const Pointer &LHS = S.Stk.pop<Pointer>();
951 const SourceInfo &Loc = S.Current->getSource(OpPC);
952 S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_unspecified)
953 << LHS.toDiagnosticString(S.getCtx())
954 << RHS.toDiagnosticString(S.getCtx());
959 S.Stk.push<BoolT>(BoolT::from(Fn(Compare(VL, VR))));
965 inline bool CmpHelperEQ<Pointer>(InterpState &S, CodePtr OpPC, CompareFn Fn) {
967 const Pointer &RHS = S.Stk.pop<Pointer>();
968 const Pointer &LHS = S.Stk.pop<Pointer>();
971 S.Stk.push<BoolT>(BoolT::from(Fn(ComparisonCategoryResult::Equal)));
980 const SourceInfo &Loc = S.Current->getSource(OpPC);
981 S.FFDiag(Loc, diag::note_constexpr_pointer_weak_comparison)
982 << P.toDiagnosticString(S.getCtx());
990 const SourceInfo &Loc = S.Current->getSource(OpPC);
991 S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_past_end)
992 << LHS.toDiagnosticString(S.getCtx());
996 const SourceInfo &Loc = S.Current->getSource(OpPC);
997 S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_past_end)
998 << RHS.toDiagnosticString(S.getCtx());
1002 S.Stk.push<BoolT>(BoolT::from(Fn(ComparisonCategoryResult::Unordered)));
1017 S.Stk.push<BoolT>(BoolT::from(Fn(Compare(VL, VR))));
1023 inline bool CmpHelperEQ<MemberPointer>(InterpState &S, CodePtr OpPC,
1025 const auto &RHS = S.Stk.pop<MemberPointer>();
1026 const auto &LHS = S.Stk.pop<MemberPointer>();
1032 const SourceInfo &Loc = S.Current->getSource(OpPC);
1033 S.FFDiag(Loc, diag::note_constexpr_mem_pointer_weak_comparison) << MD;
1042 S.Stk.push<Boolean>(Fn(ComparisonCategoryResult::Equal));
1046 S.Stk.push<Boolean>(Fn(ComparisonCategoryResult::Unordered));
1054 const SourceInfo &Loc = S.Current->getSource(OpPC);
1055 S.CCEDiag(Loc, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
1059 S.Stk.push<Boolean>(Boolean::from(Fn(LHS.compare(RHS))));
1064 bool EQ(InterpState &S, CodePtr OpPC) {
1065 return CmpHelperEQ<T>(S, OpPC, [](ComparisonCategoryResult R) {
1071 bool CMP3(InterpState &S, CodePtr OpPC, const ComparisonCategoryInfo *CmpInfo) {
1072 const T &RHS = S.Stk.pop<T>();
1073 const T &LHS = S.Stk.pop<T>();
1074 const Pointer &P = S.Stk.peek<Pointer>();
1079 const SourceInfo &Loc = S.Current->getSource(OpPC);
1080 S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_unspecified)
1081 << LHS.toDiagnosticString(S.getCtx())
1082 << RHS.toDiagnosticString(S.getCtx());
1091 return SetThreeWayComparisonField(S, OpPC, P, CmpValueInfo->getIntValue());
1095 bool NE(InterpState &S, CodePtr OpPC) {
1096 return CmpHelperEQ<T>(S, OpPC, [](ComparisonCategoryResult R) {
1102 bool LT(InterpState &S, CodePtr OpPC) {
1103 return CmpHelper<T>(S, OpPC, [](ComparisonCategoryResult R) {
1109 bool LE(InterpState &S, CodePtr OpPC) {
1110 return CmpHelper<T>(S, OpPC, [](ComparisonCategoryResult R) {
1117 bool GT(InterpState &S, CodePtr OpPC) {
1118 return CmpHelper<T>(S, OpPC, [](ComparisonCategoryResult R) {
1124 bool GE(InterpState &S, CodePtr OpPC) {
1125 return CmpHelper<T>(S, OpPC, [](ComparisonCategoryResult R) {
1136 bool InRange(InterpState &S, CodePtr OpPC) {
1137 const T RHS = S.Stk.pop<T>();
1138 const T LHS = S.Stk.pop<T>();
1139 const T Value = S.Stk.pop<T>();
1141 S.Stk.push<bool>(LHS <= Value && Value <= RHS);
1150 bool Dup(InterpState &S, CodePtr OpPC) {
1151 S.Stk.push<T>(S.Stk.peek<T>());
1156 bool Pop(InterpState &S, CodePtr OpPC) {
1157 S.Stk.pop<T>();
1166 bool Const(InterpState &S, CodePtr OpPC, const T &Arg) {
1167 S.Stk.push<T>(Arg);
1176 bool GetLocal(InterpState &S, CodePtr OpPC, uint32_t I) {
1177 const Pointer &Ptr = S.Current->getLocalPointer(I);
1178 if (!CheckLoad(S, OpPC, Ptr))
1180 S.Stk.push<T>(Ptr.deref<T>());
1188 bool SetLocal(InterpState &S, CodePtr OpPC, uint32_t I) {
1189 S.Current->setLocal<T>(I, S.Stk.pop<T>());
1194 bool GetParam(InterpState &S, CodePtr OpPC, uint32_t I) {
1195 if (S.checkingPotentialConstantExpression()) {
1198 S.Stk.push<T>(S.Current->getParam<T>(I));
1203 bool SetParam(InterpState &S, CodePtr OpPC, uint32_t I) {
1204 S.Current->setParam<T>(I, S.Stk.pop<T>());
1211 bool GetField(InterpState &S, CodePtr OpPC, uint32_t I) {
1212 const Pointer &Obj = S.Stk.peek<Pointer>();
1213 if (!CheckNull(S, OpPC, Obj, CSK_Field))
1215 if (!CheckRange(S, OpPC, Obj, CSK_Field))
1218 if (!CheckLoad(S, OpPC, Field))
1220 S.Stk.push<T>(Field.deref<T>());
1225 bool SetField(InterpState &S, CodePtr OpPC, uint32_t I) {
1226 const T &Value = S.Stk.pop<T>();
1227 const Pointer &Obj = S.Stk.peek<Pointer>();
1228 if (!CheckNull(S, OpPC, Obj, CSK_Field))
1230 if (!CheckRange(S, OpPC, Obj, CSK_Field))
1233 if (!CheckStore(S, OpPC, Field))
1243 bool GetFieldPop(InterpState &S, CodePtr OpPC, uint32_t I) {
1244 const Pointer &Obj = S.Stk.pop<Pointer>();
1245 if (!CheckNull(S, OpPC, Obj, CSK_Field))
1247 if (!CheckRange(S, OpPC, Obj, CSK_Field))
1250 if (!CheckLoad(S, OpPC, Field))
1252 S.Stk.push<T>(Field.deref<T>());
1257 bool GetThisField(InterpState &S, CodePtr OpPC, uint32_t I) {
1258 if (S.checkingPotentialConstantExpression())
1260 const Pointer &This = S.Current->getThis();
1261 if (!CheckThis(S, OpPC, This))
1264 if (!CheckLoad(S, OpPC, Field))
1266 S.Stk.push<T>(Field.deref<T>());
1271 bool SetThisField(InterpState &S, CodePtr OpPC, uint32_t I) {
1272 if (S.checkingPotentialConstantExpression())
1274 const T &Value = S.Stk.pop<T>();
1275 const Pointer &This = S.Current->getThis();
1276 if (!CheckThis(S, OpPC, This))
1279 if (!CheckStore(S, OpPC, Field))
1286 bool GetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
1287 const Pointer &Ptr = S.P.getPtrGlobal(I);
1288 if (!CheckConstant(S, OpPC, Ptr.getFieldDesc()))
1295 if (!CheckGlobalInitialized(S, OpPC, Ptr))
1298 S.Stk.push<T>(Ptr.deref<T>());
1304 bool GetGlobalUnchecked(InterpState &S, CodePtr OpPC, uint32_t I) {
1305 const Pointer &Ptr = S.P.getPtrGlobal(I);
1308 S.Stk.push<T>(Ptr.deref<T>());
1313 bool SetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
1319 bool InitGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
1320 const Pointer &P = S.P.getGlobal(I);
1321 P.deref<T>() = S.Stk.pop<T>();
1330 bool InitGlobalTemp(InterpState &S, CodePtr OpPC, uint32_t I,
1332 const Pointer &Ptr = S.P.getGlobal(I);
1334 const T Value = S.Stk.peek<T>();
1335 APValue APV = Value.toAPValue(S.getCtx());
1341 S.SeenGlobalTemporaries.push_back(
1344 Ptr.deref<T>() = S.Stk.pop<T>();
1352 inline bool InitGlobalTempComp(InterpState &S, CodePtr OpPC,
1355 const Pointer &P = S.Stk.peek<Pointer>();
1358 S.SeenGlobalTemporaries.push_back(
1362 P.toRValue(S.getCtx(), Temp->getTemporaryExpr()->getType())) {
1371 bool InitThisField(InterpState &S, CodePtr OpPC, uint32_t I) {
1372 if (S.checkingPotentialConstantExpression())
1374 const Pointer &This = S.Current->getThis();
1375 if (!CheckThis(S, OpPC, This))
1378 Field.deref<T>() = S.Stk.pop<T>();
1386 bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F,
1389 if (S.checkingPotentialConstantExpression())
1391 const Pointer &This = S.Current->getThis();
1392 if (!CheckThis(S, OpPC, This))
1395 const auto &Value = S.Stk.pop<T>();
1396 Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue(S.getCtx()));
1402 bool InitThisFieldActive(InterpState &S, CodePtr OpPC, uint32_t I) {
1403 if (S.checkingPotentialConstantExpression())
1405 const Pointer &This = S.Current->getThis();
1406 if (!CheckThis(S, OpPC, This))
1409 Field.deref<T>() = S.Stk.pop<T>();
1419 bool InitField(InterpState &S, CodePtr OpPC, uint32_t I) {
1420 const T &Value = S.Stk.pop<T>();
1421 const Pointer &Field = S.Stk.peek<Pointer>().atField(I);
1429 bool InitBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) {
1431 const T &Value = S.Stk.pop<T>();
1432 const Pointer &Field = S.Stk.peek<Pointer>().atField(F->Offset);
1433 Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue(S.getCtx()));
1440 bool InitFieldActive(InterpState &S, CodePtr OpPC, uint32_t I) {
1441 const T &Value = S.Stk.pop<T>();
1442 const Pointer &Ptr = S.Stk.pop<Pointer>();
1454 inline bool GetPtrLocal(InterpState &S, CodePtr OpPC, uint32_t I) {
1455 S.Stk.push<Pointer>(S.Current->getLocalPointer(I));
1459 inline bool GetPtrParam(InterpState &S, CodePtr OpPC, uint32_t I) {
1460 if (S.checkingPotentialConstantExpression()) {
1463 S.Stk.push<Pointer>(S.Current->getParamPointer(I));
1467 inline bool GetPtrGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
1468 S.Stk.push<Pointer>(S.P.getPtrGlobal(I));
1474 inline bool GetPtrField(InterpState &S, CodePtr OpPC, uint32_t Off) {
1475 const Pointer &Ptr = S.Stk.peek<Pointer>();
1477 if (S.getLangOpts().CPlusPlus && S.inConstantContext() &&
1478 !CheckNull(S, OpPC, Ptr, CSK_Field))
1481 if (!CheckExtern(S, OpPC, Ptr))
1483 if (!CheckRange(S, OpPC, Ptr, CSK_Field))
1485 if (!CheckArray(S, OpPC, Ptr))
1487 if (!CheckSubobject(S, OpPC, Ptr, CSK_Field))
1492 S.Stk.push<Pointer>(Ptr.atField(Off));
1496 inline bool GetPtrFieldPop(InterpState &S, CodePtr OpPC, uint32_t Off) {
1497 const Pointer &Ptr = S.Stk.pop<Pointer>();
1499 if (S.getLangOpts().CPlusPlus && S.inConstantContext() &&
1500 !CheckNull(S, OpPC, Ptr, CSK_Field))
1503 if (!CheckExtern(S, OpPC, Ptr))
1505 if (!CheckRange(S, OpPC, Ptr, CSK_Field))
1507 if (!CheckArray(S, OpPC, Ptr))
1509 if (!CheckSubobject(S, OpPC, Ptr, CSK_Field))
1515 S.Stk.push<Pointer>(Ptr.atField(Off));
1519 inline bool GetPtrThisField(InterpState &S, CodePtr OpPC, uint32_t Off) {
1520 if (S.checkingPotentialConstantExpression())
1522 const Pointer &This = S.Current->getThis();
1523 if (!CheckThis(S, OpPC, This))
1525 S.Stk.push<Pointer>(This.atField(Off));
1529 inline bool GetPtrActiveField(InterpState &S, CodePtr OpPC, uint32_t Off) {
1530 const Pointer &Ptr = S.Stk.pop<Pointer>();
1531 if (!CheckNull(S, OpPC, Ptr, CSK_Field))
1533 if (!CheckRange(S, OpPC, Ptr, CSK_Field))
1538 S.Stk.push<Pointer>(std::move(Field));
1542 inline bool GetPtrActiveThisField(InterpState &S, CodePtr OpPC, uint32_t Off) {
1543 if (S.checkingPotentialConstantExpression())
1545 const Pointer &This = S.Current->getThis();
1546 if (!CheckThis(S, OpPC, This))
1551 S.Stk.push<Pointer>(std::move(Field));
1555 inline bool GetPtrDerivedPop(InterpState &S, CodePtr OpPC, uint32_t Off) {
1556 const Pointer &Ptr = S.Stk.pop<Pointer>();
1557 if (!CheckNull(S, OpPC, Ptr, CSK_Derived))
1559 if (!CheckSubobject(S, OpPC, Ptr, CSK_Derived))
1561 if (!CheckDowncast(S, OpPC, Ptr, Off))
1564 S.Stk.push<Pointer>(Ptr.atFieldSub(Off));
1568 inline bool GetPtrBase(InterpState &S, CodePtr OpPC, uint32_t Off) {
1569 const Pointer &Ptr = S.Stk.peek<Pointer>();
1570 if (!CheckNull(S, OpPC, Ptr, CSK_Base))
1572 if (!CheckSubobject(S, OpPC, Ptr, CSK_Base))
1574 S.Stk.push<Pointer>(Ptr.atField(Off));
1578 inline bool GetPtrBasePop(InterpState &S, CodePtr OpPC, uint32_t Off) {
1579 const Pointer &Ptr = S.Stk.pop<Pointer>();
1580 if (!CheckNull(S, OpPC, Ptr, CSK_Base))
1582 if (!CheckSubobject(S, OpPC, Ptr, CSK_Base))
1584 S.Stk.push<Pointer>(Ptr.atField(Off));
1588 inline bool GetMemberPtrBasePop(InterpState &S, CodePtr OpPC, int32_t Off) {
1589 const auto &Ptr = S.Stk.pop<MemberPointer>();
1590 S.Stk.push<MemberPointer>(Ptr.atInstanceBase(Off));
1594 inline bool GetPtrThisBase(InterpState &S, CodePtr OpPC, uint32_t Off) {
1595 if (S.checkingPotentialConstantExpression())
1597 const Pointer &This = S.Current->getThis();
1598 if (!CheckThis(S, OpPC, This))
1600 S.Stk.push<Pointer>(This.atField(Off));
1604 inline bool FinishInitPop(InterpState &S, CodePtr OpPC) {
1605 const Pointer &Ptr = S.Stk.pop<Pointer>();
1613 inline bool FinishInit(InterpState &S, CodePtr OpPC) {
1614 const Pointer &Ptr = S.Stk.peek<Pointer>();
1622 inline bool Dump(InterpState &S, CodePtr OpPC) {
1623 S.Stk.dump();
1627 inline bool VirtBaseHelper(InterpState &S, CodePtr OpPC, const RecordDecl *Decl,
1634 S.Stk.push<Pointer>(Base.atField(VirtBase->Offset));
1638 inline bool GetPtrVirtBasePop(InterpState &S, CodePtr OpPC,
1641 const Pointer &Ptr = S.Stk.pop<Pointer>();
1642 if (!CheckNull(S, OpPC, Ptr, CSK_Base))
1644 return VirtBaseHelper(S, OpPC, D, Ptr);
1647 inline bool GetPtrThisVirtBase(InterpState &S, CodePtr OpPC,
1650 if (S.checkingPotentialConstantExpression())
1652 const Pointer &This = S.Current->getThis();
1653 if (!CheckThis(S, OpPC, This))
1655 return VirtBaseHelper(S, OpPC, D, S.Current->getThis());
1663 bool Load(InterpState &S, CodePtr OpPC) {
1664 const Pointer &Ptr = S.Stk.peek<Pointer>();
1665 if (!CheckLoad(S, OpPC, Ptr))
1669 S.Stk.push<T>(Ptr.deref<T>());
1674 bool LoadPop(InterpState &S, CodePtr OpPC) {
1675 const Pointer &Ptr = S.Stk.pop<Pointer>();
1676 if (!CheckLoad(S, OpPC, Ptr))
1680 S.Stk.push<T>(Ptr.deref<T>());
1685 bool Store(InterpState &S, CodePtr OpPC) {
1686 const T &Value = S.Stk.pop<T>();
1687 const Pointer &Ptr = S.Stk.peek<Pointer>();
1688 if (!CheckStore(S, OpPC, Ptr))
1697 bool StorePop(InterpState &S, CodePtr OpPC) {
1698 const T &Value = S.Stk.pop<T>();
1699 const Pointer &Ptr = S.Stk.pop<Pointer>();
1700 if (!CheckStore(S, OpPC, Ptr))
1709 bool StoreBitField(InterpState &S, CodePtr OpPC) {
1710 const T &Value = S.Stk.pop<T>();
1711 const Pointer &Ptr = S.Stk.peek<Pointer>();
1712 if (!CheckStore(S, OpPC, Ptr))
1717 Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue(S.getCtx()));
1724 bool StoreBitFieldPop(InterpState &S, CodePtr OpPC) {
1725 const T &Value = S.Stk.pop<T>();
1726 const Pointer &Ptr = S.Stk.pop<Pointer>();
1727 if (!CheckStore(S, OpPC, Ptr))
1732 Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue(S.getCtx()));
1739 bool Init(InterpState &S, CodePtr OpPC) {
1740 const T &Value = S.Stk.pop<T>();
1741 const Pointer &Ptr = S.Stk.peek<Pointer>();
1742 if (!CheckInit(S, OpPC, Ptr)) {
1752 bool InitPop(InterpState &S, CodePtr OpPC) {
1753 const T &Value = S.Stk.pop<T>();
1754 const Pointer &Ptr = S.Stk.pop<Pointer>();
1755 if (!CheckInit(S, OpPC, Ptr))
1766 bool InitElem(InterpState &S, CodePtr OpPC, uint32_t Idx) {
1767 const T &Value = S.Stk.pop<T>();
1768 const Pointer &Ptr = S.Stk.peek<Pointer>().atIndex(Idx);
1771 if (!CheckInit(S, OpPC, Ptr))
1780 bool InitElemPop(InterpState &S, CodePtr OpPC, uint32_t Idx) {
1781 const T &Value = S.Stk.pop<T>();
1782 const Pointer &Ptr = S.Stk.pop<Pointer>().atIndex(Idx);
1785 if (!CheckInit(S, OpPC, Ptr))
1792 inline bool Memcpy(InterpState &S, CodePtr OpPC) {
1793 const Pointer &Src = S.Stk.pop<Pointer>();
1794 Pointer &Dest = S.Stk.peek<Pointer>();
1796 if (!CheckLoad(S, OpPC, Src))
1799 return DoMemcpy(S, OpPC, Src, Dest);
1802 inline bool ToMemberPtr(InterpState &S, CodePtr OpPC) {
1803 const auto &Member = S.Stk.pop<MemberPointer>();
1804 const auto &Base = S.Stk.pop<Pointer>();
1806 S.Stk.push<MemberPointer>(Member.takeInstance(Base));
1810 inline bool CastMemberPtrPtr(InterpState &S, CodePtr OpPC) {
1811 const auto &MP = S.Stk.pop<MemberPointer>();
1813 if (std::optional<Pointer> Ptr = MP.toPointer(S.Ctx)) {
1814 S.Stk.push<Pointer>(*Ptr);
1825 bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
1829 S.Stk.push<Pointer>(Ptr);
1833 if (!CheckNull(S, OpPC, Ptr, CSK_ArrayIndex)) {
1836 if (S.getLangOpts().CPlusPlus)
1841 if (!CheckArray(S, OpPC, Ptr))
1860 S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_array_index)
1888 if (Invalid && S.getLangOpts().CPlusPlus)
1904 S.Stk.push<Pointer>(Ptr.asBlockPointer().Pointee,
1909 S.Stk.push<Pointer>(Ptr.atIndex(static_cast<uint64_t>(Result)));
1914 bool AddOffset(InterpState &S, CodePtr OpPC) {
1915 const T &Offset = S.Stk.pop<T>();
1916 const Pointer &Ptr = S.Stk.pop<Pointer>();
1917 return OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr);
1921 bool SubOffset(InterpState &S, CodePtr OpPC) {
1922 const T &Offset = S.Stk.pop<T>();
1923 const Pointer &Ptr = S.Stk.pop<Pointer>();
1924 return OffsetHelper<T, ArithOp::Sub>(S, OpPC, Offset, Ptr);
1928 static inline bool IncDecPtrHelper(InterpState &S, CodePtr OpPC,
1936 if (!CheckNull(S, OpPC, P, CSK_ArrayIndex))
1940 S.Stk.push<Pointer>(P);
1944 if (!OffsetHelper<OneT, Op>(S, OpPC, One, P))
1948 Ptr.deref<Pointer>() = S.Stk.pop<Pointer>();
1952 static inline bool IncPtr(InterpState &S, CodePtr OpPC) {
1953 const Pointer &Ptr = S.Stk.pop<Pointer>();
1955 if (!CheckInitialized(S, OpPC, Ptr, AK_Increment))
1958 return IncDecPtrHelper<ArithOp::Add>(S, OpPC, Ptr);
1961 static inline bool DecPtr(InterpState &S, CodePtr OpPC) {
1962 const Pointer &Ptr = S.Stk.pop<Pointer>();
1964 if (!CheckInitialized(S, OpPC, Ptr, AK_Decrement))
1967 return IncDecPtrHelper<ArithOp::Sub>(S, OpPC, Ptr);
1974 inline bool SubPtr(InterpState &S, CodePtr OpPC) {
1975 const Pointer &LHS = S.Stk.pop<Pointer>();
1976 const Pointer &RHS = S.Stk.pop<Pointer>();
1979 S.Stk.push<T>(T::from(LHS.getIndex()));
1983 if (!Pointer::hasSameBase(LHS, RHS) && S.getLangOpts().CPlusPlus) {
1989 S.Stk.push<T>();
1997 return AddSubMulHelper<T, T::sub, std::minus>(S, OpPC, A.bitWidth(), A, B);
2004 inline bool Destroy(InterpState &S, CodePtr OpPC, uint32_t I) {
2005 S.Current->destroy(I);
2013 template <PrimType TIn, PrimType TOut> bool Cast(InterpState &S, CodePtr OpPC) {
2016 S.Stk.push<U>(U::from(S.Stk.pop<T>()));
2022 inline bool CastFP(InterpState &S, CodePtr OpPC, const llvm::fltSemantics *Sem,
2024 Floating F = S.Stk.pop<Floating>();
2026 S.Stk.push<Floating>(Result);
2033 bool CastAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
2034 S.Stk.push<IntegralAP<false>>(
2035 IntegralAP<false>::from(S.Stk.pop<T>(), BitWidth));
2040 bool CastAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
2041 S.Stk.push<IntegralAP<true>>(
2042 IntegralAP<true>::from(S.Stk.pop<T>(), BitWidth));
2047 bool CastIntegralFloating(InterpState &S, CodePtr OpPC,
2050 const T &From = S.Stk.pop<T>();
2055 S.Stk.push<Floating>(Result);
2057 return CheckFloatResult(S, OpPC, Result, Status);
2061 bool CastFloatingIntegral(InterpState &S, CodePtr OpPC) {
2062 const Floating &F = S.Stk.pop<Floating>();
2065 S.Stk.push<T>(T(F.isNonZero()));
2074 const Expr *E = S.Current->getExpr(OpPC);
2077 S.CCEDiag(E, diag::note_constexpr_overflow) << F.getAPFloat() << Type;
2078 if (S.noteUndefinedBehavior()) {
2079 S.Stk.push<T>(T(Result));
2085 S.Stk.push<T>(T(Result));
2086 return CheckFloatResult(S, OpPC, F, Status);
2090 static inline bool CastFloatingIntegralAP(InterpState &S, CodePtr OpPC,
2092 const Floating &F = S.Stk.pop<Floating>();
2099 const Expr *E = S.Current->getExpr(OpPC);
2102 S.CCEDiag(E, diag::note_constexpr_overflow) << F.getAPFloat() << Type;
2103 return S.noteUndefinedBehavior();
2106 S.Stk.push<IntegralAP<true>>(IntegralAP<true>(Result));
2107 return CheckFloatResult(S, OpPC, F, Status);
2110 static inline bool CastFloatingIntegralAPS(InterpState &S, CodePtr OpPC,
2112 const Floating &F = S.Stk.pop<Floating>();
2119 const Expr *E = S.Current->getExpr(OpPC);
2122 S.CCEDiag(E, diag::note_constexpr_overflow) << F.getAPFloat() << Type;
2123 return S.noteUndefinedBehavior();
2126 S.Stk.push<IntegralAP<true>>(IntegralAP<true>(Result));
2127 return CheckFloatResult(S, OpPC, F, Status);
2131 bool CastPointerIntegral(InterpState &S, CodePtr OpPC) {
2132 const Pointer &Ptr = S.Stk.pop<Pointer>();
2137 const SourceInfo &E = S.Current->getSource(OpPC);
2138 S.CCEDiag(E, diag::note_constexpr_invalid_cast)
2139 << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
2141 S.Stk.push<T>(T::from(Ptr.getIntegerRepresentation()));
2145 static inline bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC,
2147 const Pointer &Ptr = S.Stk.pop<Pointer>();
2152 const SourceInfo &E = S.Current->getSource(OpPC);
2153 S.CCEDiag(E, diag::note_constexpr_invalid_cast)
2154 << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
2156 S.Stk.push<IntegralAP<false>>(
2161 static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC,
2163 const Pointer &Ptr = S.Stk.pop<Pointer>();
2168 const SourceInfo &E = S.Current->getSource(OpPC);
2169 S.CCEDiag(E, diag::note_constexpr_invalid_cast)
2170 << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
2172 S.Stk.push<IntegralAP<true>>(
2177 static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) {
2178 const auto &Ptr = S.Stk.peek<Pointer>();
2180 if (SrcIsVoidPtr && S.getLangOpts().CPlusPlus) {
2185 } else if (!S.getLangOpts().CPlusPlus26) {
2186 const SourceInfo &E = S.Current->getSource(OpPC);
2187 S.CCEDiag(E, diag::note_constexpr_invalid_cast)
2188 << 3 << "'void *'" << S.Current->getRange(OpPC);
2191 const SourceInfo &E = S.Current->getSource(OpPC);
2192 S.CCEDiag(E, diag::note_constexpr_invalid_cast)
2193 << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
2204 bool Zero(InterpState &S, CodePtr OpPC) {
2205 S.Stk.push<T>(T::zero());
2209 static inline bool ZeroIntAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
2210 S.Stk.push<IntegralAP<false>>(IntegralAP<false>::zero(BitWidth));
2214 static inline bool ZeroIntAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
2215 S.Stk.push<IntegralAP<true>>(IntegralAP<true>::zero(BitWidth));
2220 inline bool Null(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
2222 S.Stk.push<T>(0, Desc);
2230 inline bool This(InterpState &S, CodePtr OpPC) {
2232 if (S.checkingPotentialConstantExpression()) {
2236 const Pointer &This = S.Current->getThis();
2237 if (!CheckThis(S, OpPC, This))
2242 assert(isa<CXXMethodDecl>(S.Current->getFunction()->getDecl()));
2246 cast<CXXMethodDecl>(S.Current->getFunction()->getDecl())->getParent());
2249 S.Stk.push<Pointer>(This);
2253 inline bool RVOPtr(InterpState &S, CodePtr OpPC) {
2254 assert(S.Current->getFunction()->hasRVO());
2255 if (S.checkingPotentialConstantExpression())
2257 S.Stk.push<Pointer>(S.Current->getRVOPtr());
2267 inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) {
2271 if (S.getLangOpts().OpenCL)
2278 const SourceInfo &Loc = S.Current->getSource(OpPC);
2279 S.CCEDiag(Loc, diag::note_constexpr_negative_shift) << RHS.toAPSInt();
2280 if (!S.noteUndefinedBehavior())
2285 : ShiftDir::Left > (S, OpPC, LHS, RHS);
2289 if (LHS.isNegative() && !S.getLangOpts().CPlusPlus20) {
2294 const SourceInfo &Loc = S.Current->getSource(OpPC);
2295 S.CCEDiag(Loc, diag::note_constexpr_lshift_of_negative) << LHS.toAPSInt();
2296 if (!S.noteUndefinedBehavior())
2301 if (!CheckShift(S, OpPC, LHS, RHS, Bits))
2324 S.Stk.push<LT>(LT::from(R));
2329 inline bool Shr(InterpState &S, CodePtr OpPC) {
2332 auto RHS = S.Stk.pop<RT>();
2333 auto LHS = S.Stk.pop<LT>();
2335 return DoShift<LT, RT, ShiftDir::Right>(S, OpPC, LHS, RHS);
2339 inline bool Shl(InterpState &S, CodePtr OpPC) {
2342 auto RHS = S.Stk.pop<RT>();
2343 auto LHS = S.Stk.pop<LT>();
2345 return DoShift<LT, RT, ShiftDir::Left>(S, OpPC, LHS, RHS);
2352 inline bool NoRet(InterpState &S, CodePtr OpPC) {
2353 SourceLocation EndLoc = S.Current->getCallee()->getEndLoc();
2354 S.FFDiag(EndLoc, diag::note_constexpr_no_return);
2362 inline bool NarrowPtr(InterpState &S, CodePtr OpPC) {
2363 const Pointer &Ptr = S.Stk.pop<Pointer>();
2364 S.Stk.push<Pointer>(Ptr.narrow());
2368 inline bool ExpandPtr(InterpState &S, CodePtr OpPC) {
2369 const Pointer &Ptr = S.Stk.pop<Pointer>();
2370 S.Stk.push<Pointer>(Ptr.expand());
2383 inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) {
2384 const T &Offset = S.Stk.pop<T>();
2385 const Pointer &Ptr = S.Stk.peek<Pointer>();
2388 if (!CheckArray(S, OpPC, Ptr))
2392 if (!OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr))
2395 return NarrowPtr(S, OpPC);
2399 inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) {
2400 const T &Offset = S.Stk.pop<T>();
2401 const Pointer &Ptr = S.Stk.pop<Pointer>();
2404 if (!CheckArray(S, OpPC, Ptr))
2408 if (!OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr))
2411 return NarrowPtr(S, OpPC);
2415 inline bool ArrayElem(InterpState &S, CodePtr OpPC, uint32_t Index) {
2416 const Pointer &Ptr = S.Stk.peek<Pointer>();
2418 if (!CheckLoad(S, OpPC, Ptr))
2421 S.Stk.push<T>(Ptr.atIndex(Index).deref<T>());
2426 inline bool ArrayElemPop(InterpState &S, CodePtr OpPC, uint32_t Index) {
2427 const Pointer &Ptr = S.Stk.pop<Pointer>();
2429 if (!CheckLoad(S, OpPC, Ptr))
2432 S.Stk.push<T>(Ptr.atIndex(Index).deref<T>());
2437 inline bool CopyArray(InterpState &S, CodePtr OpPC, uint32_t SrcIndex, uint32_t DestIndex, uint32_t Size) {
2438 const auto &SrcPtr = S.Stk.pop<Pointer>();
2439 const auto &DestPtr = S.Stk.peek<Pointer>();
2444 if (!CheckLoad(S, OpPC, SP))
2456 inline bool ArrayDecay(InterpState &S, CodePtr OpPC) {
2457 const Pointer &Ptr = S.Stk.pop<Pointer>();
2460 S.Stk.push<Pointer>(Ptr);
2464 if (!CheckRange(S, OpPC, Ptr, CSK_ArrayToPointer))
2468 S.Stk.push<Pointer>(Ptr.atIndex(0));
2472 const SourceInfo &E = S.Current->getSource(OpPC);
2473 S.FFDiag(E, diag::note_constexpr_unsupported_unsized_array);
2478 inline bool CallVar(InterpState &S, CodePtr OpPC, const Function *Func,
2483 const Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);
2489 if (!(S.Current->getFunction() &&
2490 S.Current->getFunction()->isLambdaStaticInvoker() &&
2492 if (!CheckInvoke(S, OpPC, ThisPtr))
2496 if (S.checkingPotentialConstantExpression())
2500 if (!CheckCallable(S, OpPC, Func))
2503 if (!CheckCallDepth(S, OpPC))
2506 auto NewFrame = std::make_unique<InterpFrame>(S, Func, OpPC, VarArgSize);
2507 InterpFrame *FrameBefore = S.Current;
2508 S.Current = NewFrame.get();
2514 if (Interpret(S, CallResult)) {
2516 assert(S.Current == FrameBefore);
2522 S.Current = FrameBefore;
2528 inline bool Call(InterpState &S, CodePtr OpPC, const Function *Func,
2534 const Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);
2540 if (!(S.Current->getFunction() &&
2541 S.Current->getFunction()->isLambdaStaticInvoker() &&
2543 if (!CheckInvoke(S, OpPC, ThisPtr))
2548 if (!CheckCallable(S, OpPC, Func))
2551 if (Func->hasThisPointer() && S.checkingPotentialConstantExpression())
2554 if (!CheckCallDepth(S, OpPC))
2557 auto NewFrame = std::make_unique<InterpFrame>(S, Func, OpPC, VarArgSize);
2558 InterpFrame *FrameBefore = S.Current;
2559 S.Current = NewFrame.get();
2565 if (Interpret(S, CallResult)) {
2567 assert(S.Current == FrameBefore);
2573 S.Current = FrameBefore;
2577 inline bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func,
2583 Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);
2593 const CXXMethodDecl *Overrider = S.getContext().getOverridingFunction(
2600 if (!S.getLangOpts().CPlusPlus20 && Overrider->isVirtual()) {
2601 const Expr *E = S.Current->getExpr(OpPC);
2602 S.CCEDiag(E, diag::note_constexpr_virtual_call) << E->getSourceRange();
2605 Func = S.getContext().getOrCreateFunction(Overrider);
2617 return Call(S, OpPC, Func, VarArgSize);
2620 inline bool CallBI(InterpState &S, CodePtr &PC, const Function *Func,
2622 auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC);
2624 InterpFrame *FrameBefore = S.Current;
2625 S.Current = NewFrame.get();
2627 if (InterpretBuiltin(S, PC, Func, CE)) {
2631 S.Current = FrameBefore;
2635 inline bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize,
2637 const FunctionPointer &FuncPtr = S.Stk.pop<FunctionPointer>();
2641 const Expr *E = S.Current->getExpr(OpPC);
2642 S.FFDiag(E, diag::note_constexpr_null_callee)
2654 if (S.Ctx.classify(F->getDecl()->getReturnType()) !=
2655 S.Ctx.classify(CE->getType()))
2660 if (!CheckNonNullArgs(S, OpPC, F, CE, ArgSize))
2673 return CallVirt(S, OpPC, F, VarArgSize);
2675 return Call(S, OpPC, F, VarArgSize);
2678 inline bool GetFnPtr(InterpState &S, CodePtr OpPC, const Function *Func) {
2680 S.Stk.push<FunctionPointer>(Func);
2685 inline bool GetIntPtr(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
2686 const T &IntVal = S.Stk.pop<T>();
2688 S.Stk.push<Pointer>(static_cast<uint64_t>(IntVal), Desc);
2692 inline bool GetMemberPtr(InterpState &S, CodePtr OpPC, const Decl *D) {
2693 S.Stk.push<MemberPointer>(D);
2697 inline bool GetMemberPtrBase(InterpState &S, CodePtr OpPC) {
2698 const auto &MP = S.Stk.pop<MemberPointer>();
2700 S.Stk.push<Pointer>(MP.getBase());
2704 inline bool GetMemberPtrDecl(InterpState &S, CodePtr OpPC) {
2705 const auto &MP = S.Stk.pop<MemberPointer>();
2708 const auto *Func = S.getContext().getOrCreateFunction(FD);
2710 S.Stk.push<FunctionPointer>(Func);
2716 inline bool Invalid(InterpState &S, CodePtr OpPC) {
2717 const SourceLocation &Loc = S.Current->getLocation(OpPC);
2718 S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr)
2719 << S.Current->getRange(OpPC);
2723 inline bool Unsupported(InterpState &S, CodePtr OpPC) {
2724 const SourceLocation &Loc = S.Current->getLocation(OpPC);
2725 S.FFDiag(Loc, diag::note_constexpr_stmt_expr_unsupported)
2726 << S.Current->getRange(OpPC);
2731 inline bool Error(InterpState &S, CodePtr OpPC) { return false; }
2734 inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind) {
2735 const SourceLocation &Loc = S.Current->getLocation(OpPC);
2739 S.FFDiag(Loc, diag::note_constexpr_invalid_cast)
2740 << static_cast<unsigned>(Kind) << S.Current->getRange(OpPC);
2744 inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC,
2747 return CheckDeclRef(S, OpPC, DR);
2750 inline bool SizelessVectorElementSize(InterpState &S, CodePtr OpPC) {
2751 if (S.inConstantContext()) {
2752 const SourceRange &ArgRange = S.Current->getRange(OpPC);
2753 const Expr *E = S.Current->getExpr(OpPC);
2754 S.CCEDiag(E, diag::note_constexpr_non_const_vectorelements) << ArgRange;
2759 inline bool Assume(InterpState &S, CodePtr OpPC) {
2760 const auto Val = S.Stk.pop<Boolean>();
2766 const SourceLocation &Loc = S.Current->getLocation(OpPC);
2767 S.CCEDiag(Loc, diag::note_constexpr_assumption_failed);
2772 inline bool OffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E) {
2775 ArrayIndices.emplace_back(S.Stk.pop<int64_t>());
2778 if (!InterpretOffsetOf(S, OpPC, E, ArrayIndices, Result))
2781 S.Stk.push<T>(T::from(Result));
2787 inline bool CheckNonNullArg(InterpState &S, CodePtr OpPC) {
2788 const T &Arg = S.Stk.peek<T>();
2792 const SourceLocation &Loc = S.Current->getLocation(OpPC);
2793 S.CCEDiag(Loc, diag::note_non_null_attribute_failed);
2798 void diagnoseEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED,
2802 inline bool CheckEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED) {
2805 const APSInt Val = S.Stk.peek<T>().toAPSInt();
2807 if (S.inConstantContext())
2808 diagnoseEnumValue(S, OpPC, ED, Val);
2814 inline bool DecayPtr(InterpState &S, CodePtr OpPC) {
2819 const FromT &OldPtr = S.Stk.pop<FromT>();
2820 S.Stk.push<ToT>(ToT(OldPtr.getIntegerRepresentation(), nullptr));
2824 inline bool CheckDecl(InterpState &S, CodePtr OpPC, const VarDecl *VD) {
2832 if (VD == S.EvaluatingDecl)
2835 if (!VD->isUsableInConstantExpressions(S.getCtx())) {
2836 S.CCEDiag(VD->getLocation(), diag::note_constexpr_static_local)
2843 inline bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
2846 if (!CheckDynamicMemoryAllocation(S, OpPC))
2849 DynamicAllocator &Allocator = S.getAllocator();
2850 Block *B = Allocator.allocate(Desc, S.Ctx.getEvalID());
2853 S.Stk.push<Pointer>(B, sizeof(InlineDescriptor));
2859 inline bool AllocN(InterpState &S, CodePtr OpPC, PrimType T, const Expr *Source,
2861 if (!CheckDynamicMemoryAllocation(S, OpPC))
2864 SizeT NumElements = S.Stk.pop<SizeT>();
2865 if (!CheckArraySize(S, OpPC, &NumElements, primSize(T), IsNoThrow)) {
2870 S.Stk.push<Pointer>(0, nullptr);
2874 DynamicAllocator &Allocator = S.getAllocator();
2876 S.Ctx.getEvalID());
2878 S.Stk.push<Pointer>(B, sizeof(InlineDescriptor));
2884 inline bool AllocCN(InterpState &S, CodePtr OpPC, const Descriptor *ElementDesc,
2886 if (!CheckDynamicMemoryAllocation(S, OpPC))
2889 SizeT NumElements = S.Stk.pop<SizeT>();
2890 if (!CheckArraySize(S, OpPC, &NumElements, ElementDesc->getSize(),
2896 S.Stk.push<Pointer>(0, ElementDesc);
2900 DynamicAllocator &Allocator = S.getAllocator();
2902 S.Ctx.getEvalID());
2905 S.Stk.push<Pointer>(B, sizeof(InlineDescriptor));
2910 bool RunDestructors(InterpState &S, CodePtr OpPC, const Block *B);
2911 static inline bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm) {
2912 if (!CheckDynamicMemoryAllocation(S, OpPC))
2920 const Pointer &Ptr = S.Stk.pop<Pointer>();
2927 const SourceInfo &Loc = S.Current->getSource(OpPC);
2928 S.FFDiag(Loc, diag::note_constexpr_delete_subobject)
2929 << Ptr.toDiagnosticString(S.getCtx()) << Ptr.isOnePastEnd();
2936 if (!CheckDeleteSource(S, OpPC, Source, Ptr))
2943 if (!RunDestructors(S, OpPC, BlockToDelete))
2946 DynamicAllocator &Allocator = S.getAllocator();
2950 if (!Allocator.deallocate(Source, BlockToDelete, S)) {
2952 const SourceInfo &Loc = S.Current->getSource(OpPC);
2953 S.FFDiag(Loc, diag::note_constexpr_double_delete);
2956 return CheckNewDeleteForms(S, OpPC, WasArrayAlloc, DeleteIsArrayForm,
2964 template <typename T> inline T ReadArg(InterpState &S, CodePtr &OpPC) {
2967 return reinterpret_cast<T>(S.P.getNativePointer(ID));
2973 template <> inline Floating ReadArg<Floating>(InterpState &S, CodePtr &OpPC) {
2980 inline IntegralAP<false> ReadArg<IntegralAP<false>>(InterpState &S,
2988 inline IntegralAP<true> ReadArg<IntegralAP<true>>(InterpState &S,