Skip to content

Commit 21b99e1

Browse files
authored
[clang][bytecode] Check reads for null block pointers (#157695)
All pointer types can be null, so check that independently from the pointer type. Fixes #157650
1 parent c883b67 commit 21b99e1

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -792,18 +792,18 @@ bool CheckLocalLoad(InterpState &S, CodePtr OpPC, const Block *B) {
792792

793793
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
794794
AccessKinds AK) {
795-
// Block pointers are the only ones we can actually read from.
796-
if (!Ptr.isBlockPointer()) {
797-
if (Ptr.isZero()) {
798-
const auto &Src = S.Current->getSource(OpPC);
795+
if (Ptr.isZero()) {
796+
const auto &Src = S.Current->getSource(OpPC);
799797

800-
if (Ptr.isField())
801-
S.FFDiag(Src, diag::note_constexpr_null_subobject) << CSK_Field;
802-
else
803-
S.FFDiag(Src, diag::note_constexpr_access_null) << AK;
804-
}
798+
if (Ptr.isField())
799+
S.FFDiag(Src, diag::note_constexpr_null_subobject) << CSK_Field;
800+
else
801+
S.FFDiag(Src, diag::note_constexpr_access_null) << AK;
805802
return false;
806803
}
804+
// Block pointers are the only ones we can actually read from.
805+
if (!Ptr.isBlockPointer())
806+
return false;
807807

808808
if (!Ptr.block()->isAccessible()) {
809809
if (!CheckLive(S, OpPC, Ptr, AK))

clang/test/AST/ByteCode/references.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
2-
// RUN: %clang_cc1 -verify=ref,both %s
2+
// RUN: %clang_cc1 -verify=ref,both %s
33

44

55
constexpr int a = 10;
@@ -178,3 +178,19 @@ namespace Params {
178178

179179
static_assert(foo());
180180
}
181+
182+
namespace ReadFromNullBlockPtr {
183+
struct S {
184+
int *const &t;
185+
};
186+
187+
void foo(int x) {
188+
constexpr S s = {&x}; // both-error {{must be initialized by a constant expression}} \
189+
// both-note {{reference to temporary}} \
190+
// both-note {{created here}} \
191+
// ref-note {{declared here}}
192+
static_assert(s.t == &x, ""); // both-error {{not an integral constant expression}} \
193+
// expected-note {{read of dereferenced null pointer}} \
194+
// ref-note {{initializer of 's' is not a constant expression}}
195+
}
196+
}

0 commit comments

Comments
 (0)