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