Skip to content

Commit e0acf65

Browse files
authored
[clang][bytecode] Call CheckFinalLoad in all language modes (llvm#154496)
Fixes llvm#153997
1 parent 1ff7c8b commit e0acf65

File tree

3 files changed

+23
-18
lines changed

3 files changed

+23
-18
lines changed

clang/lib/AST/ByteCode/EvalEmitter.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,8 @@ template <> bool EvalEmitter::emitRet<PT_Ptr>(const SourceInfo &Info) {
213213
if (!Ptr.isZero() && !Ptr.isDereferencable())
214214
return false;
215215

216-
if (S.getLangOpts().CPlusPlus11 && Ptr.isBlockPointer() &&
217-
!CheckFinalLoad(S, OpPC, Ptr)) {
216+
if (!Ptr.isZero() && !CheckFinalLoad(S, OpPC, Ptr))
218217
return false;
219-
}
220218

221219
// Never allow reading from a non-const pointer, unless the memory
222220
// has been created in this evaluation.

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -839,19 +839,10 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
839839
/// This is not used by any of the opcodes directly. It's used by
840840
/// EvalEmitter to do the final lvalue-to-rvalue conversion.
841841
bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
842-
if (!Ptr.isBlockPointer()) {
843-
if (Ptr.isZero()) {
844-
const auto &Src = S.Current->getSource(OpPC);
845-
846-
if (Ptr.isField())
847-
S.FFDiag(Src, diag::note_constexpr_null_subobject) << CSK_Field;
848-
else
849-
S.FFDiag(Src, diag::note_constexpr_access_null) << AK_Read;
850-
}
842+
assert(!Ptr.isZero());
843+
if (!Ptr.isBlockPointer())
851844
return false;
852-
}
853845

854-
assert(Ptr.isBlockPointer());
855846
if (!Ptr.block()->isAccessible()) {
856847
if (!CheckLive(S, OpPC, Ptr, AK_Read))
857848
return false;

clang/test/AST/ByteCode/cxx98.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,12 @@ template struct C<cval>;
1818

1919
/// FIXME: This example does not get properly diagnosed in the new interpreter.
2020
extern const int recurse1;
21-
const int recurse2 = recurse1; // both-note {{declared here}}
21+
const int recurse2 = recurse1; // ref-note {{declared here}}
2222
const int recurse1 = 1;
2323
int array1[recurse1];
2424
int array2[recurse2]; // ref-warning 2{{variable length array}} \
25-
// both-note {{initializer of 'recurse2' is not a constant expression}} \
26-
// expected-warning {{variable length array}} \
27-
// expected-error {{variable length array}}
25+
// ref-note {{initializer of 'recurse2' is not a constant expression}} \
26+
// expected-warning 2{{variable length array}}
2827

2928
int NCI; // both-note {{declared here}}
3029
int NCIA[NCI]; // both-warning {{variable length array}} \
@@ -64,3 +63,20 @@ const int b = 1 / 0; // both-warning {{division by zero is undefined}} \
6463
// both-note {{declared here}}
6564
_Static_assert(b, ""); // both-error {{not an integral constant expression}} \
6665
// both-note {{initializer of 'b' is not a constant expression}}
66+
67+
#ifdef __SIZEOF_INT128__
68+
/// The if statement tries an ltor conversion on an inactive union member.
69+
union InactiveReadUnion{
70+
int a;
71+
__uint128_t n;
72+
};
73+
74+
int inactiveRead(void) {
75+
const InactiveReadUnion U = {1};
76+
77+
if (U.n)
78+
return 1;
79+
80+
return 0;
81+
}
82+
#endif

0 commit comments

Comments
 (0)