[clang] [clang][Interp] Diagnose reads from non-const global variables (PR #71919)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 11 23:15:23 PST 2023


Timm =?utf-8?q?Bäder?= <tbaeder at redhat.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/71919 at github.com>


================
@@ -1005,12 +1008,23 @@ bool SetThisField(InterpState &S, CodePtr OpPC, uint32_t I) {
 template <PrimType Name, class T = typename PrimConv<Name>::T>
 bool GetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
   const Block *B = S.P.getGlobal(I);
+
+  if (!CheckConstant(S, OpPC, B->getDescriptor()))
+    return false;
   if (B->isExtern())
     return false;
   S.Stk.push<T>(B->deref<T>());
   return true;
 }
 
+/// Same as GetGlobal, but without the checks.
+template <PrimType Name, class T = typename PrimConv<Name>::T>
+bool GetGlobalUnchecked(InterpState &S, CodePtr OpPC, uint32_t I) {
+  auto *B = S.P.getGlobal(I);
+  S.Stk.push<T>(B->deref<T>());
+  return true;
+}
+
----------------
tbaederr wrote:

It's a bit involved because `GetGlobal` can't just call `GetGlobalUnchecked` since they would both have to call `S.P.getGlobal(I)`... I mean, that's not a problem per se but a little ugly and slower than it needs to be. So we'd have to use a third function that just does `S.Stk.push<T>(B->deref<T>()); return true;`.

https://github.com/llvm/llvm-project/pull/71919


More information about the cfe-commits mailing list