[clang][bytecode] Call CheckFinalLoad in all language modes (#154496)
Fixes #153997
This commit is contained in:
parent
1ff7c8bf0d
commit
e0acf6592b
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user