@@ -930,14 +930,23 @@ static bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
930930 if (F->isValid () && F->hasBody () && F->isConstexpr ())
931931 return true ;
932932
933+ const FunctionDecl *DiagDecl = F->getDecl ();
934+ const FunctionDecl *Definition = nullptr ;
935+ DiagDecl->getBody (Definition);
936+
937+ if (!Definition && S.checkingPotentialConstantExpression () &&
938+ DiagDecl->isConstexpr ()) {
939+ return false ;
940+ }
941+
933942 // Implicitly constexpr.
934943 if (F->isLambdaStaticInvoker ())
935944 return true ;
936945
937946 // Bail out if the function declaration itself is invalid. We will
938947 // have produced a relevant diagnostic while parsing it, so just
939948 // note the problematic sub-expression.
940- if (F-> getDecl () ->isInvalidDecl ())
949+ if (DiagDecl ->isInvalidDecl ())
941950 return Invalid (S, OpPC);
942951
943952 // Diagnose failed assertions specially.
@@ -955,64 +964,61 @@ static bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
955964 }
956965 }
957966
958- if (S.getLangOpts ().CPlusPlus11 ) {
959- const FunctionDecl *DiagDecl = F->getDecl ();
960-
961- // Invalid decls have been diagnosed before.
962- if (DiagDecl->isInvalidDecl ())
963- return false ;
967+ if (!S.getLangOpts ().CPlusPlus11 ) {
968+ S.FFDiag (S.Current ->getLocation (OpPC),
969+ diag::note_invalid_subexpr_in_const_expr);
970+ return false ;
971+ }
964972
965- // If this function is not constexpr because it is an inherited
966- // non-constexpr constructor, diagnose that directly.
967- const auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
968- if (CD && CD->isInheritingConstructor ()) {
969- const auto *Inherited = CD->getInheritedConstructor ().getConstructor ();
970- if (!Inherited->isConstexpr ())
971- DiagDecl = CD = Inherited;
972- }
973+ // Invalid decls have been diagnosed before.
974+ if (DiagDecl->isInvalidDecl ())
975+ return false ;
973976
974- // Silently reject constructors of invalid classes. The invalid class
975- // has been rejected elsewhere before.
976- if (CD && CD->getParent ()->isInvalidDecl ())
977- return false ;
977+ // If this function is not constexpr because it is an inherited
978+ // non-constexpr constructor, diagnose that directly.
979+ const auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
980+ if (CD && CD->isInheritingConstructor ()) {
981+ const auto *Inherited = CD->getInheritedConstructor ().getConstructor ();
982+ if (!Inherited->isConstexpr ())
983+ DiagDecl = CD = Inherited;
984+ }
978985
979- // FIXME: If DiagDecl is an implicitly-declared special member function
980- // or an inheriting constructor, we should be much more explicit about why
981- // it's not constexpr.
982- if (CD && CD->isInheritingConstructor ()) {
983- S.FFDiag (S.Current ->getLocation (OpPC),
984- diag::note_constexpr_invalid_inhctor, 1 )
985- << CD->getInheritedConstructor ().getConstructor ()->getParent ();
986- S.Note (DiagDecl->getLocation (), diag::note_declared_at);
987- } else {
988- // Don't emit anything if the function isn't defined and we're checking
989- // for a constant expression. It might be defined at the point we're
990- // actually calling it.
991- bool IsExtern = DiagDecl->getStorageClass () == SC_Extern;
992- bool IsDefined = F->isDefined ();
993- if (!IsDefined && !IsExtern && DiagDecl->isConstexpr () &&
994- S.checkingPotentialConstantExpression ())
995- return false ;
986+ // Silently reject constructors of invalid classes. The invalid class
987+ // has been rejected elsewhere before.
988+ if (CD && CD->getParent ()->isInvalidDecl ())
989+ return false ;
996990
997- // If the declaration is defined, declared 'constexpr' _and_ has a body,
998- // the below diagnostic doesn't add anything useful.
999- if (DiagDecl->isDefined () && DiagDecl->isConstexpr () &&
1000- DiagDecl->hasBody ())
1001- return false ;
991+ // FIXME: If DiagDecl is an implicitly-declared special member function
992+ // or an inheriting constructor, we should be much more explicit about why
993+ // it's not constexpr.
994+ if (CD && CD->isInheritingConstructor ()) {
995+ S.FFDiag (S.Current ->getLocation (OpPC), diag::note_constexpr_invalid_inhctor,
996+ 1 )
997+ << CD->getInheritedConstructor ().getConstructor ()->getParent ();
998+ S.Note (DiagDecl->getLocation (), diag::note_declared_at);
999+ } else {
1000+ // Don't emit anything if the function isn't defined and we're checking
1001+ // for a constant expression. It might be defined at the point we're
1002+ // actually calling it.
1003+ bool IsExtern = DiagDecl->getStorageClass () == SC_Extern;
1004+ bool IsDefined = F->isDefined ();
1005+ if (!IsDefined && !IsExtern && DiagDecl->isConstexpr () &&
1006+ S.checkingPotentialConstantExpression ())
1007+ return false ;
10021008
1003- S.FFDiag (S.Current ->getLocation (OpPC),
1004- diag::note_constexpr_invalid_function, 1 )
1005- << DiagDecl->isConstexpr () << (bool )CD << DiagDecl;
1009+ // If the declaration is defined, declared 'constexpr' _and_ has a body,
1010+ // the below diagnostic doesn't add anything useful.
1011+ if (DiagDecl->isDefined () && DiagDecl->isConstexpr () && DiagDecl->hasBody ())
1012+ return false ;
10061013
1007- if (DiagDecl->getDefinition ())
1008- S.Note (DiagDecl->getDefinition ()->getLocation (),
1009- diag::note_declared_at);
1010- else
1011- S.Note (DiagDecl->getLocation (), diag::note_declared_at);
1012- }
1013- } else {
10141014 S.FFDiag (S.Current ->getLocation (OpPC),
1015- diag::note_invalid_subexpr_in_const_expr);
1015+ diag::note_constexpr_invalid_function, 1 )
1016+ << DiagDecl->isConstexpr () << (bool )CD << DiagDecl;
1017+
1018+ if (DiagDecl->getDefinition ())
1019+ S.Note (DiagDecl->getDefinition ()->getLocation (), diag::note_declared_at);
1020+ else
1021+ S.Note (DiagDecl->getLocation (), diag::note_declared_at);
10161022 }
10171023
10181024 return false ;
0 commit comments