@@ -81,14 +81,41 @@ static void assignInteger(Pointer &Dest, PrimType ValueT, const APSInt &Value) {
8181 ValueT, { Dest.deref <T>() = T::from (static_cast <T>(Value)); });
8282}
8383
84+ template <PrimType Name, class V = typename PrimConv<Name>::T>
85+ static bool retBI (InterpState &S, const CallExpr *Call, unsigned BuiltinID) {
86+ // The return value of the function is already on the stack.
87+ // Remove it, get rid of all the arguments and add it back.
88+ const V &Val = S.Stk .pop <V>();
89+ if (!Context::isUnevaluatedBuiltin (BuiltinID)) {
90+ for (int32_t I = Call->getNumArgs () - 1 ; I >= 0 ; --I) {
91+ const Expr *A = Call->getArg (I);
92+ PrimType Ty = S.getContext ().classify (A).value_or (PT_Ptr);
93+ TYPE_SWITCH (Ty, S.Stk .discard <T>());
94+ }
95+ }
96+ S.Stk .push <V>(Val);
97+ return true ;
98+ }
99+
84100static bool retPrimValue (InterpState &S, CodePtr OpPC,
85- std::optional<PrimType> &T) {
86- if (!T)
87- return RetVoid (S, OpPC);
101+ std::optional<PrimType> &T, const CallExpr *Call,
102+ unsigned BuiltinID) {
103+
104+ if (!T) {
105+ if (!Context::isUnevaluatedBuiltin (BuiltinID)) {
106+ for (int32_t I = Call->getNumArgs () - 1 ; I >= 0 ; --I) {
107+ const Expr *A = Call->getArg (I);
108+ PrimType Ty = S.getContext ().classify (A).value_or (PT_Ptr);
109+ TYPE_SWITCH (Ty, S.Stk .discard <T>());
110+ }
111+ }
112+
113+ return true ;
114+ }
88115
89116#define RET_CASE (X ) \
90117 case X: \
91- return Ret <X>(S, OpPC );
118+ return retBI <X>(S, Call, BuiltinID );
92119 switch (*T) {
93120 RET_CASE (PT_Ptr);
94121 RET_CASE (PT_Float);
@@ -147,17 +174,16 @@ static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC,
147174 // The one above that, potentially the one for std::is_constant_evaluated().
148175 if (S.inConstantContext () && !S.checkingPotentialConstantExpression () &&
149176 S.getEvalStatus ().Diag &&
150- (Depth == 1 || (Depth == 2 && isStdCall (Caller ->getCallee ())))) {
151- if (Caller-> Caller && isStdCall (Caller ->getCallee ())) {
152- const Expr *E = Caller->Caller -> getExpr (Caller->getRetPC ());
177+ (Depth == 0 || (Depth == 1 && isStdCall (Frame ->getCallee ())))) {
178+ if (Caller && isStdCall (Frame ->getCallee ())) {
179+ const Expr *E = Caller->getExpr (Caller->getRetPC ());
153180 S.report (E->getExprLoc (),
154181 diag::warn_is_constant_evaluated_always_true_constexpr)
155182 << " std::is_constant_evaluated" << E->getSourceRange ();
156183 } else {
157- const Expr *E = Frame->Caller ->getExpr (Frame->getRetPC ());
158- S.report (E->getExprLoc (),
184+ S.report (Call->getExprLoc (),
159185 diag::warn_is_constant_evaluated_always_true_constexpr)
160- << " __builtin_is_constant_evaluated" << E ->getSourceRange ();
186+ << " __builtin_is_constant_evaluated" << Call ->getSourceRange ();
161187 }
162188 }
163189
@@ -2675,7 +2701,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
26752701 return false ;
26762702 }
26772703
2678- return retPrimValue (S, OpPC, ReturnT);
2704+ return retPrimValue (S, OpPC, ReturnT, Call, BuiltinID );
26792705}
26802706
26812707bool InterpretOffsetOf (InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
0 commit comments