@@ -986,6 +986,241 @@ void diagnoseEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED,
986
986
}
987
987
}
988
988
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
+
989
1224
bool Interpret (InterpState &S, APValue &Result) {
990
1225
// The current stack frame when we started Interpret().
991
1226
// This is being used by the ops to determine wheter
0 commit comments