[clang][bytecode] Call CheckFinalLoad in all language modes (#154496)

Fixes #153997
This commit is contained in:
Timm Baeder 2025-08-21 08:24:09 +02:00 committed by GitHub
parent 1ff7c8bf0d
commit e0acf6592b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 18 deletions

View File

@ -213,10 +213,8 @@ template <> bool EvalEmitter::emitRet<PT_Ptr>(const SourceInfo &Info) {
if (!Ptr.isZero() && !Ptr.isDereferencable())
return false;
if (S.getLangOpts().CPlusPlus11 && Ptr.isBlockPointer() &&
!CheckFinalLoad(S, OpPC, Ptr)) {
if (!Ptr.isZero() && !CheckFinalLoad(S, OpPC, Ptr))
return false;
}
// Never allow reading from a non-const pointer, unless the memory
// has been created in this evaluation.

View File

@ -839,19 +839,10 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
/// This is not used by any of the opcodes directly. It's used by
/// EvalEmitter to do the final lvalue-to-rvalue conversion.
bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
if (!Ptr.isBlockPointer()) {
if (Ptr.isZero()) {
const auto &Src = S.Current->getSource(OpPC);
if (Ptr.isField())
S.FFDiag(Src, diag::note_constexpr_null_subobject) << CSK_Field;
else
S.FFDiag(Src, diag::note_constexpr_access_null) << AK_Read;
}
assert(!Ptr.isZero());
if (!Ptr.isBlockPointer())
return false;
}
assert(Ptr.isBlockPointer());
if (!Ptr.block()->isAccessible()) {
if (!CheckLive(S, OpPC, Ptr, AK_Read))
return false;

View File

@ -18,13 +18,12 @@ template struct C<cval>;
/// FIXME: This example does not get properly diagnosed in the new interpreter.
extern const int recurse1;
const int recurse2 = recurse1; // both-note {{declared here}}
const int recurse2 = recurse1; // ref-note {{declared here}}
const int recurse1 = 1;
int array1[recurse1];
int array2[recurse2]; // ref-warning 2{{variable length array}} \
// both-note {{initializer of 'recurse2' is not a constant expression}} \
// expected-warning {{variable length array}} \
// expected-error {{variable length array}}
// ref-note {{initializer of 'recurse2' is not a constant expression}} \
// expected-warning 2{{variable length array}}
int NCI; // both-note {{declared here}}
int NCIA[NCI]; // both-warning {{variable length array}} \
@ -64,3 +63,20 @@ const int b = 1 / 0; // both-warning {{division by zero is undefined}} \
// both-note {{declared here}}
_Static_assert(b, ""); // both-error {{not an integral constant expression}} \
// both-note {{initializer of 'b' is not a constant expression}}
#ifdef __SIZEOF_INT128__
/// The if statement tries an ltor conversion on an inactive union member.
union InactiveReadUnion{
int a;
__uint128_t n;
};
int inactiveRead(void) {
const InactiveReadUnion U = {1};
if (U.n)
return 1;
return 0;
}
#endif