Skip to content

Commit 4bf356b

Browse files
authored
[clang][bytecode] Start implementing builtin_is_within_lifetime (#137765)
1 parent 13b443f commit 4bf356b

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

+49
Original file line numberDiff line numberDiff line change
@@ -2198,6 +2198,50 @@ static bool interp__builtin_object_size(InterpState &S, CodePtr OpPC,
21982198
return true;
21992199
}
22002200

2201+
static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
2202+
const CallExpr *Call) {
2203+
2204+
if (!S.inConstantContext())
2205+
return false;
2206+
2207+
const Pointer &Ptr = S.Stk.peek<Pointer>();
2208+
2209+
auto Error = [&](int Diag) {
2210+
bool CalledFromStd = false;
2211+
const auto *Callee = S.Current->getCallee();
2212+
if (Callee && Callee->isInStdNamespace()) {
2213+
const IdentifierInfo *Identifier = Callee->getIdentifier();
2214+
CalledFromStd = Identifier && Identifier->isStr("is_within_lifetime");
2215+
}
2216+
S.CCEDiag(CalledFromStd
2217+
? S.Current->Caller->getSource(S.Current->getRetPC())
2218+
: S.Current->getSource(OpPC),
2219+
diag::err_invalid_is_within_lifetime)
2220+
<< (CalledFromStd ? "std::is_within_lifetime"
2221+
: "__builtin_is_within_lifetime")
2222+
<< Diag;
2223+
return false;
2224+
};
2225+
2226+
if (Ptr.isZero())
2227+
return Error(0);
2228+
if (Ptr.isOnePastEnd())
2229+
return Error(1);
2230+
2231+
bool Result = true;
2232+
if (!Ptr.isActive()) {
2233+
Result = false;
2234+
} else {
2235+
if (!CheckLive(S, OpPC, Ptr, AK_Read))
2236+
return false;
2237+
if (!CheckMutable(S, OpPC, Ptr))
2238+
return false;
2239+
}
2240+
2241+
pushInteger(S, Result, Call->getType());
2242+
return true;
2243+
}
2244+
22012245
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
22022246
uint32_t BuiltinID) {
22032247
if (!S.getASTContext().BuiltinInfo.isConstantEvaluated(BuiltinID))
@@ -2707,6 +2751,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
27072751
return false;
27082752
break;
27092753

2754+
case Builtin::BI__builtin_is_within_lifetime:
2755+
if (!interp__builtin_is_within_lifetime(S, OpPC, Call))
2756+
return false;
2757+
break;
2758+
27102759
default:
27112760
S.FFDiag(S.Current->getLocation(OpPC),
27122761
diag::note_invalid_subexpr_in_const_expr)

clang/test/AST/ByteCode/builtin-functions.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -1709,3 +1709,36 @@ namespace Invalid {
17091709
static_assert(test() == 0); // both-error {{not an integral constant expression}} \
17101710
// both-note {{in call to}}
17111711
}
1712+
1713+
#if __cplusplus >= 202002L
1714+
namespace WithinLifetime {
1715+
constexpr int a = 10;
1716+
static_assert(__builtin_is_within_lifetime(&a));
1717+
1718+
consteval int IsActive(bool ReadB) {
1719+
union {
1720+
int a, b;
1721+
} A;
1722+
A.a = 10;
1723+
if (ReadB)
1724+
return __builtin_is_within_lifetime(&A.b);
1725+
return __builtin_is_within_lifetime(&A.a);
1726+
}
1727+
static_assert(IsActive(false));
1728+
static_assert(!IsActive(true));
1729+
1730+
static_assert(__builtin_is_within_lifetime((void*)nullptr)); // both-error {{not an integral constant expression}} \
1731+
// both-note {{'__builtin_is_within_lifetime' cannot be called with a null pointer}}
1732+
1733+
constexpr int i = 2;
1734+
constexpr int arr[2]{};
1735+
void f() {
1736+
__builtin_is_within_lifetime(&i + 1); // both-error {{call to consteval function '__builtin_is_within_lifetime' is not a constant expression}} \
1737+
// both-note {{'__builtin_is_within_lifetime' cannot be called with a one-past-the-end pointer}} \
1738+
// both-warning {{expression result unused}}
1739+
__builtin_is_within_lifetime(arr + 2); // both-error {{call to consteval function '__builtin_is_within_lifetime' is not a constant expression}} \
1740+
// both-note {{'__builtin_is_within_lifetime' cannot be called with a one-past-the-end pointer}} \
1741+
// both-warning {{expression result unused}}
1742+
}
1743+
}
1744+
#endif

0 commit comments

Comments
 (0)