Skip to content

Commit 5cefb9a

Browse files
authored
[clang][bytecode] Fix __builtin_is_within_lifetime in initializers (#147480)
1 parent 65f94d7 commit 5cefb9a

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2208,15 +2208,27 @@ static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
22082208
if (Ptr.isOnePastEnd())
22092209
return Error(1);
22102210

2211-
bool Result = true;
2211+
bool Result = Ptr.getLifetime() != Lifetime::Ended;
22122212
if (!Ptr.isActive()) {
22132213
Result = false;
22142214
} else {
22152215
if (!CheckLive(S, OpPC, Ptr, AK_Read))
22162216
return false;
22172217
if (!CheckMutable(S, OpPC, Ptr))
22182218
return false;
2219+
if (!CheckDummy(S, OpPC, Ptr, AK_Read))
2220+
return false;
2221+
}
2222+
2223+
// Check if we're currently running an initializer.
2224+
for (InterpFrame *Frame = S.Current; Frame; Frame = Frame->Caller) {
2225+
if (const Function *F = Frame->getFunction();
2226+
F && F->isConstructor() && Frame->getThis().block() == Ptr.block()) {
2227+
return Error(2);
2228+
}
22192229
}
2230+
if (S.EvaluatingDecl && Ptr.getDeclDesc()->asVarDecl() == S.EvaluatingDecl)
2231+
return Error(2);
22202232

22212233
pushInteger(S, Result, Call->getType());
22222234
return true;

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,26 @@ namespace WithinLifetime {
17381738
// both-note {{'__builtin_is_within_lifetime' cannot be called with a one-past-the-end pointer}} \
17391739
// both-warning {{expression result unused}}
17401740
}
1741+
1742+
1743+
constexpr bool self = __builtin_is_within_lifetime(&self); // both-error {{must be initialized by a constant expression}} \
1744+
// both-note {{'__builtin_is_within_lifetime' cannot be called with a pointer to an object whose lifetime has not yet begun}} \
1745+
// ref-error {{call to consteval function '__builtin_is_within_lifetime' is not a constant expression}} \
1746+
// ref-note {{initializer of 'self' is not a constant expression}} \
1747+
// ref-note {{declared here}}
1748+
1749+
int nontCE(int p) { // both-note {{declared here}}
1750+
return __builtin_is_within_lifetime(&p); // both-error {{call to consteval function}} \
1751+
// both-note {{function parameter 'p' with unknown value cannot be used in a constant expression}}
1752+
}
1753+
1754+
1755+
struct XStd {
1756+
consteval XStd() {
1757+
__builtin_is_within_lifetime(this); // both-note {{cannot be called with a pointer to an object whose lifetime has not yet begun}}
1758+
}
1759+
} xstd; // both-error {{is not a constant expression}} \
1760+
// both-note {{in call to}}
17411761
}
17421762

17431763
#ifdef __SIZEOF_INT128__

0 commit comments

Comments
 (0)