@@ -579,57 +579,62 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
579579 return false ;
580580 }
581581
582- if (!F->isConstexpr () || !F->hasBody ()) {
583- const SourceLocation &Loc = S.Current ->getLocation (OpPC);
584- if (S.getLangOpts ().CPlusPlus11 ) {
585- const FunctionDecl *DiagDecl = F->getDecl ();
582+ if (F->isConstexpr () && F->hasBody () &&
583+ (F->getDecl ()->isConstexpr () || F->getDecl ()->hasAttr <MSConstexprAttr>()))
584+ return true ;
586585
587- // Invalid decls have been diagnosed before .
588- if (DiagDecl-> isInvalidDecl ())
589- return false ;
586+ // Implicitly constexpr .
587+ if (F-> isLambdaStaticInvoker ())
588+ return true ;
590589
591- // If this function is not constexpr because it is an inherited
592- // non-constexpr constructor, diagnose that directly.
593- const auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
594- if (CD && CD->isInheritingConstructor ()) {
595- const auto *Inherited = CD->getInheritedConstructor ().getConstructor ();
596- if (!Inherited->isConstexpr ())
597- DiagDecl = CD = Inherited;
598- }
590+ const SourceLocation &Loc = S.Current ->getLocation (OpPC);
591+ if (S.getLangOpts ().CPlusPlus11 ) {
592+ const FunctionDecl *DiagDecl = F->getDecl ();
593+
594+ // Invalid decls have been diagnosed before.
595+ if (DiagDecl->isInvalidDecl ())
596+ return false ;
597+
598+ // If this function is not constexpr because it is an inherited
599+ // non-constexpr constructor, diagnose that directly.
600+ const auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
601+ if (CD && CD->isInheritingConstructor ()) {
602+ const auto *Inherited = CD->getInheritedConstructor ().getConstructor ();
603+ if (!Inherited->isConstexpr ())
604+ DiagDecl = CD = Inherited;
605+ }
599606
600- // FIXME: If DiagDecl is an implicitly-declared special member function
601- // or an inheriting constructor, we should be much more explicit about why
602- // it's not constexpr.
603- if (CD && CD->isInheritingConstructor ()) {
604- S.FFDiag (Loc, diag::note_constexpr_invalid_inhctor, 1 )
607+ // FIXME: If DiagDecl is an implicitly-declared special member function
608+ // or an inheriting constructor, we should be much more explicit about why
609+ // it's not constexpr.
610+ if (CD && CD->isInheritingConstructor ()) {
611+ S.FFDiag (Loc, diag::note_constexpr_invalid_inhctor, 1 )
605612 << CD->getInheritedConstructor ().getConstructor ()->getParent ();
606- S.Note (DiagDecl->getLocation (), diag::note_declared_at);
607- } else {
608- // Don't emit anything if the function isn't defined and we're checking
609- // for a constant expression. It might be defined at the point we're
610- // actually calling it.
611- bool IsExtern = DiagDecl->getStorageClass () == SC_Extern;
612- if (!DiagDecl->isDefined () && !IsExtern &&
613- S.checkingPotentialConstantExpression ())
614- return false ;
613+ S.Note (DiagDecl->getLocation (), diag::note_declared_at);
614+ } else {
615+ // Don't emit anything if the function isn't defined and we're checking
616+ // for a constant expression. It might be defined at the point we're
617+ // actually calling it.
618+ bool IsExtern = DiagDecl->getStorageClass () == SC_Extern;
619+ if (!DiagDecl->isDefined () && !IsExtern && DiagDecl-> isConstexpr () &&
620+ S.checkingPotentialConstantExpression ())
621+ return false ;
615622
616- // If the declaration is defined, declared 'constexpr' _and_ has a body,
617- // the below diagnostic doesn't add anything useful.
618- if (DiagDecl->isDefined () && DiagDecl->isConstexpr () &&
619- DiagDecl->hasBody ())
620- return false ;
623+ // If the declaration is defined, declared 'constexpr' _and_ has a body,
624+ // the below diagnostic doesn't add anything useful.
625+ if (DiagDecl->isDefined () && DiagDecl->isConstexpr () &&
626+ DiagDecl->hasBody ())
627+ return false ;
621628
622- S.FFDiag (Loc, diag::note_constexpr_invalid_function, 1 )
629+ S.FFDiag (Loc, diag::note_constexpr_invalid_function, 1 )
623630 << DiagDecl->isConstexpr () << (bool )CD << DiagDecl;
624- S.Note (DiagDecl->getLocation (), diag::note_declared_at);
625- }
626- } else {
627- S.FFDiag (Loc, diag::note_invalid_subexpr_in_const_expr);
631+ S.Note (DiagDecl->getLocation (), diag::note_declared_at);
628632 }
629- return false ;
633+ } else {
634+ S.FFDiag (Loc, diag::note_invalid_subexpr_in_const_expr);
630635 }
631636
632- return true ;
637+ return false ;
633638}
634639
635640bool CheckCallDepth (InterpState &S, CodePtr OpPC) {
0 commit comments