@@ -119,6 +119,36 @@ static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result,
119119#undef RET_CASE
120120}
121121
122+ static bool interp__builtin_is_constant_evaluated (InterpState &S, CodePtr OpPC,
123+ const InterpFrame *Frame,
124+ const CallExpr *Call) {
125+ // The current frame is the one for __builtin_is_constant_evaluated.
126+ // The one above that, potentially the one for std::is_constant_evaluated().
127+ if (S.inConstantContext () && !S.checkingPotentialConstantExpression () &&
128+ Frame->Caller && S.getEvalStatus ().Diag ) {
129+ auto isStdCall = [](const FunctionDecl *F) -> bool {
130+ return F && F->isInStdNamespace () && F->getIdentifier () &&
131+ F->getIdentifier ()->isStr (" is_constant_evaluated" );
132+ };
133+ const InterpFrame *Caller = Frame->Caller ;
134+
135+ if (Caller->Caller && isStdCall (Caller->getCallee ())) {
136+ const Expr *E = Caller->Caller ->getExpr (Caller->getRetPC ());
137+ S.report (E->getExprLoc (),
138+ diag::warn_is_constant_evaluated_always_true_constexpr)
139+ << " std::is_constant_evaluated" ;
140+ } else {
141+ const Expr *E = Frame->Caller ->getExpr (Frame->getRetPC ());
142+ S.report (E->getExprLoc (),
143+ diag::warn_is_constant_evaluated_always_true_constexpr)
144+ << " __builtin_is_constant_evaluated" ;
145+ }
146+ }
147+
148+ S.Stk .push <Boolean>(Boolean::from (S.inConstantContext ()));
149+ return true ;
150+ }
151+
122152static bool interp__builtin_strcmp (InterpState &S, CodePtr OpPC,
123153 const InterpFrame *Frame,
124154 const CallExpr *Call) {
@@ -924,7 +954,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
924954
925955 switch (F->getBuiltinID ()) {
926956 case Builtin::BI__builtin_is_constant_evaluated:
927- S.Stk .push <Boolean>(Boolean::from (S.inConstantContext ()));
957+ if (!interp__builtin_is_constant_evaluated (S, OpPC, Frame, Call))
958+ return false ;
928959 break ;
929960 case Builtin::BI__builtin_assume:
930961 case Builtin::BI__assume:
0 commit comments