https://github.com/vgvassilev updated 
https://github.com/llvm/llvm-project/pull/196894

>From 016918be154464cda6b5033dae70eb247e4a7a84 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev <[email protected]>
Date: Mon, 11 May 2026 07:18:19 +0000
Subject: [PATCH] [clang-repl] Unpoison Value in SetValueNoAlloc to clear MSan
 varargs taint.

__clang_Interpreter_SetValueNoAlloc receives the runtime value
through a varargs ABI: the JIT-emitted caller copies real bits into
the varargs slot, and the runtime callee reads them via va_arg and
stores them in the user-provided Value. MSan tracks parameter
shadow through TLS, but the JIT does not emit MSan TLS shadow
setup for its calls, so the varargs source reads as uninitialized.

The end result is correct bits with an uninit shadow on the stored
Value; downstream reads (V.getLongDouble(), V.convertTo<T>()) then
report use-of-uninitialized-value. The bits are real -- only the
shadow is wrong.

Unpoison the written Value before returning, gated on
__has_feature(memory_sanitizer) so non-MSan builds compile out
to nothing.
---
 .../Interpreter/InterpreterValuePrinter.cpp   | 20 ++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Interpreter/InterpreterValuePrinter.cpp 
b/clang/lib/Interpreter/InterpreterValuePrinter.cpp
index 1754e7812469a..6bf5b1c8403d7 100644
--- a/clang/lib/Interpreter/InterpreterValuePrinter.cpp
+++ b/clang/lib/Interpreter/InterpreterValuePrinter.cpp
@@ -31,6 +31,21 @@
 #include <sstream>
 #include <string>
 
+// MSan cannot track value shadow across the JIT/native varargs boundary in
+// __clang_Interpreter_SetValueNoAlloc: the JIT-emitted caller does not set
+// up MSan TLS shadow, so writes via va_arg propagate uninit shadow into the
+// resulting Value. Unpoison the written Value before returning.
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+#include <sanitizer/msan_interface.h>
+#define CLANG_INTERP_MSAN_UNPOISON(p, n) __msan_unpoison((p), (n))
+#else
+#define CLANG_INTERP_MSAN_UNPOISON(p, n) ((void)0)
+#endif
+#else
+#define CLANG_INTERP_MSAN_UNPOISON(p, n) ((void)0)
+#endif
+
 #define DEBUG_TYPE "interp-value"
 
 using namespace clang;
@@ -651,8 +666,10 @@ __clang_Interpreter_SetValueNoAlloc(void *This, void 
*OutVal, void *OpaqueType,
   Value &VRef = *(Value *)OutVal;
   Interpreter *I = static_cast<Interpreter *>(This);
   VRef = Value(I, OpaqueType);
-  if (VRef.isVoid())
+  if (VRef.isVoid()) {
+    CLANG_INTERP_MSAN_UNPOISON(OutVal, sizeof(Value));
     return;
+  }
 
   va_list args;
   va_start(args, /*last named param*/ OpaqueType);
@@ -721,6 +738,7 @@ __clang_Interpreter_SetValueNoAlloc(void *This, void 
*OutVal, void *OpaqueType,
     }
   }
   va_end(args);
+  CLANG_INTERP_MSAN_UNPOISON(OutVal, sizeof(Value));
 }
 }
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to