@@ -986,6 +986,241 @@ void diagnoseEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED,
986986 }
987987}
988988
989+ bool CallVar (InterpState &S, CodePtr OpPC, const Function *Func,
990+ uint32_t VarArgSize) {
991+ if (Func->hasThisPointer ()) {
992+ size_t ArgSize = Func->getArgSize () + VarArgSize;
993+ size_t ThisOffset = ArgSize - (Func->hasRVO () ? primSize (PT_Ptr) : 0 );
994+ const Pointer &ThisPtr = S.Stk .peek <Pointer>(ThisOffset);
995+
996+ // If the current function is a lambda static invoker and
997+ // the function we're about to call is a lambda call operator,
998+ // skip the CheckInvoke, since the ThisPtr is a null pointer
999+ // anyway.
1000+ if (!(S.Current ->getFunction () &&
1001+ S.Current ->getFunction ()->isLambdaStaticInvoker () &&
1002+ Func->isLambdaCallOperator ())) {
1003+ if (!CheckInvoke (S, OpPC, ThisPtr))
1004+ return false ;
1005+ }
1006+
1007+ if (S.checkingPotentialConstantExpression ())
1008+ return false ;
1009+ }
1010+
1011+ if (!CheckCallable (S, OpPC, Func))
1012+ return false ;
1013+
1014+ if (!CheckCallDepth (S, OpPC))
1015+ return false ;
1016+
1017+ auto NewFrame = std::make_unique<InterpFrame>(S, Func, OpPC, VarArgSize);
1018+ InterpFrame *FrameBefore = S.Current ;
1019+ S.Current = NewFrame.get ();
1020+
1021+ APValue CallResult;
1022+ // Note that we cannot assert(CallResult.hasValue()) here since
1023+ // Ret() above only sets the APValue if the curent frame doesn't
1024+ // have a caller set.
1025+ if (Interpret (S, CallResult)) {
1026+ NewFrame.release (); // Frame was delete'd already.
1027+ assert (S.Current == FrameBefore);
1028+ return true ;
1029+ }
1030+
1031+ // Interpreting the function failed somehow. Reset to
1032+ // previous state.
1033+ S.Current = FrameBefore;
1034+ return false ;
1035+ }
1036+
1037+ bool Call (InterpState &S, CodePtr OpPC, const Function *Func,
1038+ uint32_t VarArgSize) {
1039+ if (Func->hasThisPointer ()) {
1040+ size_t ArgSize = Func->getArgSize () + VarArgSize;
1041+ size_t ThisOffset = ArgSize - (Func->hasRVO () ? primSize (PT_Ptr) : 0 );
1042+
1043+ const Pointer &ThisPtr = S.Stk .peek <Pointer>(ThisOffset);
1044+
1045+ // If the current function is a lambda static invoker and
1046+ // the function we're about to call is a lambda call operator,
1047+ // skip the CheckInvoke, since the ThisPtr is a null pointer
1048+ // anyway.
1049+ if (S.Current ->getFunction () &&
1050+ S.Current ->getFunction ()->isLambdaStaticInvoker () &&
1051+ Func->isLambdaCallOperator ()) {
1052+ assert (ThisPtr.isZero ());
1053+ } else {
1054+ if (!CheckInvoke (S, OpPC, ThisPtr))
1055+ return false ;
1056+ }
1057+ }
1058+
1059+ if (!CheckCallable (S, OpPC, Func))
1060+ return false ;
1061+
1062+ // FIXME: The isConstructor() check here is not always right. The current
1063+ // constant evaluator is somewhat inconsistent in when it allows a function
1064+ // call when checking for a constant expression.
1065+ if (Func->hasThisPointer () && S.checkingPotentialConstantExpression () &&
1066+ !Func->isConstructor ())
1067+ return false ;
1068+
1069+ if (!CheckCallDepth (S, OpPC))
1070+ return false ;
1071+
1072+ auto NewFrame = std::make_unique<InterpFrame>(S, Func, OpPC, VarArgSize);
1073+ InterpFrame *FrameBefore = S.Current ;
1074+ S.Current = NewFrame.get ();
1075+
1076+ APValue CallResult;
1077+ // Note that we cannot assert(CallResult.hasValue()) here since
1078+ // Ret() above only sets the APValue if the curent frame doesn't
1079+ // have a caller set.
1080+ if (Interpret (S, CallResult)) {
1081+ NewFrame.release (); // Frame was delete'd already.
1082+ assert (S.Current == FrameBefore);
1083+ return true ;
1084+ }
1085+
1086+ // Interpreting the function failed somehow. Reset to
1087+ // previous state.
1088+ S.Current = FrameBefore;
1089+ return false ;
1090+ }
1091+
1092+ bool CallVirt (InterpState &S, CodePtr OpPC, const Function *Func,
1093+ uint32_t VarArgSize) {
1094+ assert (Func->hasThisPointer ());
1095+ assert (Func->isVirtual ());
1096+ size_t ArgSize = Func->getArgSize () + VarArgSize;
1097+ size_t ThisOffset = ArgSize - (Func->hasRVO () ? primSize (PT_Ptr) : 0 );
1098+ Pointer &ThisPtr = S.Stk .peek <Pointer>(ThisOffset);
1099+
1100+ const CXXRecordDecl *DynamicDecl = nullptr ;
1101+ {
1102+ Pointer TypePtr = ThisPtr;
1103+ while (TypePtr.isBaseClass ())
1104+ TypePtr = TypePtr.getBase ();
1105+
1106+ QualType DynamicType = TypePtr.getType ();
1107+ if (DynamicType->isPointerType () || DynamicType->isReferenceType ())
1108+ DynamicDecl = DynamicType->getPointeeCXXRecordDecl ();
1109+ else
1110+ DynamicDecl = DynamicType->getAsCXXRecordDecl ();
1111+ }
1112+ assert (DynamicDecl);
1113+
1114+ const auto *StaticDecl = cast<CXXRecordDecl>(Func->getParentDecl ());
1115+ const auto *InitialFunction = cast<CXXMethodDecl>(Func->getDecl ());
1116+ const CXXMethodDecl *Overrider = S.getContext ().getOverridingFunction (
1117+ DynamicDecl, StaticDecl, InitialFunction);
1118+
1119+ if (Overrider != InitialFunction) {
1120+ // DR1872: An instantiated virtual constexpr function can't be called in a
1121+ // constant expression (prior to C++20). We can still constant-fold such a
1122+ // call.
1123+ if (!S.getLangOpts ().CPlusPlus20 && Overrider->isVirtual ()) {
1124+ const Expr *E = S.Current ->getExpr (OpPC);
1125+ S.CCEDiag (E, diag::note_constexpr_virtual_call) << E->getSourceRange ();
1126+ }
1127+
1128+ Func = S.getContext ().getOrCreateFunction (Overrider);
1129+
1130+ const CXXRecordDecl *ThisFieldDecl =
1131+ ThisPtr.getFieldDesc ()->getType ()->getAsCXXRecordDecl ();
1132+ if (Func->getParentDecl ()->isDerivedFrom (ThisFieldDecl)) {
1133+ // If the function we call is further DOWN the hierarchy than the
1134+ // FieldDesc of our pointer, just go up the hierarchy of this field
1135+ // the furthest we can go.
1136+ while (ThisPtr.isBaseClass ())
1137+ ThisPtr = ThisPtr.getBase ();
1138+ }
1139+ }
1140+
1141+ if (!Call (S, OpPC, Func, VarArgSize))
1142+ return false ;
1143+
1144+ // Covariant return types. The return type of Overrider is a pointer
1145+ // or reference to a class type.
1146+ if (Overrider != InitialFunction &&
1147+ Overrider->getReturnType ()->isPointerOrReferenceType () &&
1148+ InitialFunction->getReturnType ()->isPointerOrReferenceType ()) {
1149+ QualType OverriderPointeeType =
1150+ Overrider->getReturnType ()->getPointeeType ();
1151+ QualType InitialPointeeType =
1152+ InitialFunction->getReturnType ()->getPointeeType ();
1153+ // We've called Overrider above, but calling code expects us to return what
1154+ // InitialFunction returned. According to the rules for covariant return
1155+ // types, what InitialFunction returns needs to be a base class of what
1156+ // Overrider returns. So, we need to do an upcast here.
1157+ unsigned Offset = S.getContext ().collectBaseOffset (
1158+ InitialPointeeType->getAsRecordDecl (),
1159+ OverriderPointeeType->getAsRecordDecl ());
1160+ return GetPtrBasePop (S, OpPC, Offset);
1161+ }
1162+
1163+ return true ;
1164+ }
1165+
1166+ bool CallBI (InterpState &S, CodePtr &PC, const Function *Func,
1167+ const CallExpr *CE) {
1168+ auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC);
1169+
1170+ InterpFrame *FrameBefore = S.Current ;
1171+ S.Current = NewFrame.get ();
1172+
1173+ if (InterpretBuiltin (S, PC, Func, CE)) {
1174+ NewFrame.release ();
1175+ return true ;
1176+ }
1177+ S.Current = FrameBefore;
1178+ return false ;
1179+ }
1180+
1181+ bool CallPtr (InterpState &S, CodePtr OpPC, uint32_t ArgSize,
1182+ const CallExpr *CE) {
1183+ const FunctionPointer &FuncPtr = S.Stk .pop <FunctionPointer>();
1184+
1185+ const Function *F = FuncPtr.getFunction ();
1186+ if (!F) {
1187+ const auto *E = cast<CallExpr>(S.Current ->getExpr (OpPC));
1188+ S.FFDiag (E, diag::note_constexpr_null_callee)
1189+ << const_cast <Expr *>(E->getCallee ()) << E->getSourceRange ();
1190+ return false ;
1191+ }
1192+
1193+ if (!FuncPtr.isValid () || !F->getDecl ())
1194+ return Invalid (S, OpPC);
1195+
1196+ assert (F);
1197+
1198+ // This happens when the call expression has been cast to
1199+ // something else, but we don't support that.
1200+ if (S.Ctx .classify (F->getDecl ()->getReturnType ()) !=
1201+ S.Ctx .classify (CE->getType ()))
1202+ return false ;
1203+
1204+ // Check argument nullability state.
1205+ if (F->hasNonNullAttr ()) {
1206+ if (!CheckNonNullArgs (S, OpPC, F, CE, ArgSize))
1207+ return false ;
1208+ }
1209+
1210+ assert (ArgSize >= F->getWrittenArgSize ());
1211+ uint32_t VarArgSize = ArgSize - F->getWrittenArgSize ();
1212+
1213+ // We need to do this explicitly here since we don't have the necessary
1214+ // information to do it automatically.
1215+ if (F->isThisPointerExplicit ())
1216+ VarArgSize -= align (primSize (PT_Ptr));
1217+
1218+ if (F->isVirtual ())
1219+ return CallVirt (S, OpPC, F, VarArgSize);
1220+
1221+ return Call (S, OpPC, F, VarArgSize);
1222+ }
1223+
9891224bool Interpret (InterpState &S, APValue &Result) {
9901225 // The current stack frame when we started Interpret().
9911226 // This is being used by the ops to determine wheter
0 commit comments