[clang][bytecode] Start implementing builtin_is_within_lifetime (#137765)
This commit is contained in:
@@ -2198,6 +2198,50 @@ static bool interp__builtin_object_size(InterpState &S, CodePtr OpPC,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
|
||||
const CallExpr *Call) {
|
||||
|
||||
if (!S.inConstantContext())
|
||||
return false;
|
||||
|
||||
const Pointer &Ptr = S.Stk.peek<Pointer>();
|
||||
|
||||
auto Error = [&](int Diag) {
|
||||
bool CalledFromStd = false;
|
||||
const auto *Callee = S.Current->getCallee();
|
||||
if (Callee && Callee->isInStdNamespace()) {
|
||||
const IdentifierInfo *Identifier = Callee->getIdentifier();
|
||||
CalledFromStd = Identifier && Identifier->isStr("is_within_lifetime");
|
||||
}
|
||||
S.CCEDiag(CalledFromStd
|
||||
? S.Current->Caller->getSource(S.Current->getRetPC())
|
||||
: S.Current->getSource(OpPC),
|
||||
diag::err_invalid_is_within_lifetime)
|
||||
<< (CalledFromStd ? "std::is_within_lifetime"
|
||||
: "__builtin_is_within_lifetime")
|
||||
<< Diag;
|
||||
return false;
|
||||
};
|
||||
|
||||
if (Ptr.isZero())
|
||||
return Error(0);
|
||||
if (Ptr.isOnePastEnd())
|
||||
return Error(1);
|
||||
|
||||
bool Result = true;
|
||||
if (!Ptr.isActive()) {
|
||||
Result = false;
|
||||
} else {
|
||||
if (!CheckLive(S, OpPC, Ptr, AK_Read))
|
||||
return false;
|
||||
if (!CheckMutable(S, OpPC, Ptr))
|
||||
return false;
|
||||
}
|
||||
|
||||
pushInteger(S, Result, Call->getType());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
|
||||
uint32_t BuiltinID) {
|
||||
if (!S.getASTContext().BuiltinInfo.isConstantEvaluated(BuiltinID))
|
||||
@@ -2707,6 +2751,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
|
||||
return false;
|
||||
break;
|
||||
|
||||
case Builtin::BI__builtin_is_within_lifetime:
|
||||
if (!interp__builtin_is_within_lifetime(S, OpPC, Call))
|
||||
return false;
|
||||
break;
|
||||
|
||||
default:
|
||||
S.FFDiag(S.Current->getLocation(OpPC),
|
||||
diag::note_invalid_subexpr_in_const_expr)
|
||||
|
||||
Reference in New Issue
Block a user