@@ -870,7 +870,8 @@ bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
870870 return true ;
871871}
872872
873- bool CheckStore (InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
873+ bool CheckStore (InterpState &S, CodePtr OpPC, const Pointer &Ptr,
874+ bool WillBeActivated) {
874875 if (!Ptr.isBlockPointer () || Ptr.isZero ())
875876 return false ;
876877
@@ -885,7 +886,7 @@ bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
885886 return false ;
886887 if (!CheckRange (S, OpPC, Ptr, AK_Assign))
887888 return false ;
888- if (!CheckActive (S, OpPC, Ptr, AK_Assign))
889+ if (!WillBeActivated && ! CheckActive (S, OpPC, Ptr, AK_Assign))
889890 return false ;
890891 if (!CheckGlobal (S, OpPC, Ptr))
891892 return false ;
@@ -932,14 +933,23 @@ static bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
932933 if (F->isValid () && F->hasBody () && F->isConstexpr ())
933934 return true ;
934935
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+
935945 // Implicitly constexpr.
936946 if (F->isLambdaStaticInvoker ())
937947 return true ;
938948
939949 // Bail out if the function declaration itself is invalid. We will
940950 // have produced a relevant diagnostic while parsing it, so just
941951 // note the problematic sub-expression.
942- if (F-> getDecl () ->isInvalidDecl ())
952+ if (DiagDecl ->isInvalidDecl ())
943953 return Invalid (S, OpPC);
944954
945955 // Diagnose failed assertions specially.
@@ -957,64 +967,61 @@ static bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
957967 }
958968 }
959969
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 ;
970+ if (!S.getLangOpts ().CPlusPlus11 ) {
971+ S.FFDiag (S.Current ->getLocation (OpPC),
972+ diag::note_invalid_subexpr_in_const_expr);
973+ return false ;
974+ }
966975
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- }
976+ // Invalid decls have been diagnosed before.
977+ if (DiagDecl->isInvalidDecl ())
978+ return false ;
975979
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 ;
980+ // If this function is not constexpr because it is an inherited
981+ // non-constexpr constructor, diagnose that directly.
982+ const auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
983+ if (CD && CD->isInheritingConstructor ()) {
984+ const auto *Inherited = CD->getInheritedConstructor ().getConstructor ();
985+ if (!Inherited->isConstexpr ())
986+ DiagDecl = CD = Inherited;
987+ }
980988
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 ;
989+ // Silently reject constructors of invalid classes. The invalid class
990+ // has been rejected elsewhere before.
991+ if (CD && CD->getParent ()->isInvalidDecl ())
992+ return false ;
998993
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 ;
994+ // FIXME: If DiagDecl is an implicitly-declared special member function
995+ // or an inheriting constructor, we should be much more explicit about why
996+ // it's not constexpr.
997+ if (CD && CD->isInheritingConstructor ()) {
998+ S.FFDiag (S.Current ->getLocation (OpPC), diag::note_constexpr_invalid_inhctor,
999+ 1 )
1000+ << CD->getInheritedConstructor ().getConstructor ()->getParent ();
1001+ S.Note (DiagDecl->getLocation (), diag::note_declared_at);
1002+ } else {
1003+ // Don't emit anything if the function isn't defined and we're checking
1004+ // for a constant expression. It might be defined at the point we're
1005+ // actually calling it.
1006+ bool IsExtern = DiagDecl->getStorageClass () == SC_Extern;
1007+ bool IsDefined = F->isDefined ();
1008+ if (!IsDefined && !IsExtern && DiagDecl->isConstexpr () &&
1009+ S.checkingPotentialConstantExpression ())
1010+ return false ;
10041011
1005- S.FFDiag (S.Current ->getLocation (OpPC),
1006- diag::note_constexpr_invalid_function, 1 )
1007- << DiagDecl->isConstexpr () << (bool )CD << DiagDecl;
1012+ // If the declaration is defined, declared 'constexpr' _and_ has a body,
1013+ // the below diagnostic doesn't add anything useful.
1014+ if (DiagDecl->isDefined () && DiagDecl->isConstexpr () && DiagDecl->hasBody ())
1015+ return false ;
10081016
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 {
10161017 S.FFDiag (S.Current ->getLocation (OpPC),
1017- diag::note_invalid_subexpr_in_const_expr);
1018+ diag::note_constexpr_invalid_function, 1 )
1019+ << DiagDecl->isConstexpr () << (bool )CD << DiagDecl;
1020+
1021+ if (DiagDecl->getDefinition ())
1022+ S.Note (DiagDecl->getDefinition ()->getLocation (), diag::note_declared_at);
1023+ else
1024+ S.Note (DiagDecl->getLocation (), diag::note_declared_at);
10181025 }
10191026
10201027 return false ;
0 commit comments