@@ -919,45 +919,19 @@ bool CheckInit(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
919919 return true ;
920920}
921921
922- static bool CheckCallable (InterpState &S, CodePtr OpPC, const Function *F) {
923-
924- if (F->isVirtual () && !S.getLangOpts ().CPlusPlus20 ) {
925- const SourceLocation &Loc = S.Current ->getLocation (OpPC);
926- S.CCEDiag (Loc, diag::note_constexpr_virtual_call);
927- return false ;
928- }
929-
930- if (S.checkingPotentialConstantExpression () && S.Current ->getDepth () != 0 )
931- return false ;
932-
933- if (F->isValid () && F->hasBody () && F->isConstexpr ())
934- return true ;
935-
936- const FunctionDecl *DiagDecl = F->getDecl ();
937- const FunctionDecl *Definition = nullptr ;
938- DiagDecl->getBody (Definition);
939-
940- if (!Definition && S.checkingPotentialConstantExpression () &&
941- DiagDecl->isConstexpr ()) {
942- return false ;
943- }
944-
945- // Implicitly constexpr.
946- if (F->isLambdaStaticInvoker ())
947- return true ;
948-
922+ static bool diagnoseCallableDecl (InterpState &S, CodePtr OpPC,
923+ const FunctionDecl *DiagDecl) {
949924 // Bail out if the function declaration itself is invalid. We will
950925 // have produced a relevant diagnostic while parsing it, so just
951926 // note the problematic sub-expression.
952927 if (DiagDecl->isInvalidDecl ())
953928 return Invalid (S, OpPC);
954929
955930 // Diagnose failed assertions specially.
956- if (S.Current ->getLocation (OpPC).isMacroID () &&
957- F->getDecl ()->getIdentifier ()) {
931+ if (S.Current ->getLocation (OpPC).isMacroID () && DiagDecl->getIdentifier ()) {
958932 // FIXME: Instead of checking for an implementation-defined function,
959933 // check and evaluate the assert() macro.
960- StringRef Name = F-> getDecl () ->getName ();
934+ StringRef Name = DiagDecl ->getName ();
961935 bool AssertFailed =
962936 Name == " __assert_rtn" || Name == " __assert_fail" || Name == " _wassert" ;
963937 if (AssertFailed) {
@@ -1004,7 +978,7 @@ static bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
1004978 // for a constant expression. It might be defined at the point we're
1005979 // actually calling it.
1006980 bool IsExtern = DiagDecl->getStorageClass () == SC_Extern;
1007- bool IsDefined = F ->isDefined ();
981+ bool IsDefined = DiagDecl ->isDefined ();
1008982 if (!IsDefined && !IsExtern && DiagDecl->isConstexpr () &&
1009983 S.checkingPotentialConstantExpression ())
1010984 return false ;
@@ -1027,6 +1001,35 @@ static bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
10271001 return false ;
10281002}
10291003
1004+ static bool CheckCallable (InterpState &S, CodePtr OpPC, const Function *F) {
1005+ if (F->isVirtual () && !S.getLangOpts ().CPlusPlus20 ) {
1006+ const SourceLocation &Loc = S.Current ->getLocation (OpPC);
1007+ S.CCEDiag (Loc, diag::note_constexpr_virtual_call);
1008+ return false ;
1009+ }
1010+
1011+ if (S.checkingPotentialConstantExpression () && S.Current ->getDepth () != 0 )
1012+ return false ;
1013+
1014+ if (F->isValid () && F->hasBody () && F->isConstexpr ())
1015+ return true ;
1016+
1017+ const FunctionDecl *DiagDecl = F->getDecl ();
1018+ const FunctionDecl *Definition = nullptr ;
1019+ DiagDecl->getBody (Definition);
1020+
1021+ if (!Definition && S.checkingPotentialConstantExpression () &&
1022+ DiagDecl->isConstexpr ()) {
1023+ return false ;
1024+ }
1025+
1026+ // Implicitly constexpr.
1027+ if (F->isLambdaStaticInvoker ())
1028+ return true ;
1029+
1030+ return diagnoseCallableDecl (S, OpPC, DiagDecl);
1031+ }
1032+
10301033static bool CheckCallDepth (InterpState &S, CodePtr OpPC) {
10311034 if ((S.Current ->getDepth () + 1 ) > S.getLangOpts ().ConstexprCallDepth ) {
10321035 S.FFDiag (S.Current ->getSource (OpPC),
@@ -1500,6 +1503,21 @@ bool CheckDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
15001503 return CheckActive (S, OpPC, Ptr, AK_Destroy);
15011504}
15021505
1506+ // / Opcode. Check if the function decl can be called at compile time.
1507+ bool CheckFunctionDecl (InterpState &S, CodePtr OpPC, const FunctionDecl *FD) {
1508+ if (S.checkingPotentialConstantExpression () && S.Current ->getDepth () != 0 )
1509+ return false ;
1510+
1511+ const FunctionDecl *Definition = nullptr ;
1512+ const Stmt *Body = FD->getBody (Definition);
1513+
1514+ if (Definition && Body &&
1515+ (Definition->isConstexpr () || Definition->hasAttr <MSConstexprAttr>()))
1516+ return true ;
1517+
1518+ return diagnoseCallableDecl (S, OpPC, FD);
1519+ }
1520+
15031521static void compileFunction (InterpState &S, const Function *Func) {
15041522 const FunctionDecl *Definition = Func->getDecl ()->getDefinition ();
15051523 if (!Definition)
0 commit comments