[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}} \