@@ -579,57 +579,62 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
579
579
return false ;
580
580
}
581
581
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 ;
586
585
587
- // Invalid decls have been diagnosed before .
588
- if (DiagDecl-> isInvalidDecl ())
589
- return false ;
586
+ // Implicitly constexpr .
587
+ if (F-> isLambdaStaticInvoker ())
588
+ return true ;
590
589
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
+ }
599
606
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 )
605
612
<< 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 ;
615
622
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 ;
621
628
622
- S.FFDiag (Loc, diag::note_constexpr_invalid_function, 1 )
629
+ S.FFDiag (Loc, diag::note_constexpr_invalid_function, 1 )
623
630
<< 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);
628
632
}
629
- return false ;
633
+ } else {
634
+ S.FFDiag (Loc, diag::note_invalid_subexpr_in_const_expr);
630
635
}
631
636
632
- return true ;
637
+ return false ;
633
638
}
634
639
635
640
bool CheckCallDepth (InterpState &S, CodePtr OpPC) {
0 commit comments