[clang][bytecode] Reject null pointers in CheckStore() (#156645)
In the attached test case, the global variable later only points to
gargbage, because the MaterializeTemporaryExpr used to initialize it is
a local variable, which is gone by the time we try to evaluate the
store.
Fixes #156223
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 06b2bdc..f1b9104 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -870,7 +870,7 @@
}
bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
- if (!Ptr.isBlockPointer())
+ if (!Ptr.isBlockPointer() || Ptr.isZero())
return false;
if (!Ptr.block()->isAccessible()) {
diff --git a/clang/test/AST/ByteCode/cxx23.cpp b/clang/test/AST/ByteCode/cxx23.cpp
index 2182d7c..72c751d 100644
--- a/clang/test/AST/ByteCode/cxx23.cpp
+++ b/clang/test/AST/ByteCode/cxx23.cpp
@@ -83,6 +83,11 @@
}
constexpr int k0 = k(0);
+namespace ThreadLocalStore {
+ thread_local int &&a = 0;
+ void store() { a = 42; }
+}
+
#if __cplusplus >= 202302L
constexpr int &b = b; // all-error {{must be initialized by a constant expression}} \
// all-note {{initializer of 'b' is not a constant expression}} \