[llvm] [orc-rt] Add ORC_RT_LOG_PUB_S for logging runtime strings. (PR #209401)
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 14 01:37:35 PDT 2026
https://github.com/lhames created https://github.com/llvm/llvm-project/pull/209401
ORC_RT_LOG requires its format to be a string literal, so the specifier for a runtime C string cannot be written at the call site by hand -- and it differs by backend: os_log redacts a plain "%s" argument to <private> unless it carries a "%{public}s" annotation, which libc's printf does not understand.
Add ORC_RT_LOG_PUB_S, which expands to "%{public}s" on the os_log backend and plain "%s" everywhere else. Call sites compose it into the format by literal adjacency, so the format stays a single literal on every backend:
ORC_RT_LOG(Info, General, "resolved " ORC_RT_LOG_PUB_S, SymbolName);
LoggingTest covers the compile/format-check path (including os_log builds); the orc-rt-log-check delivery test confirms os_log publishes the string rather than redacting it to <private>.
>From 5e475fd0fb909c67aa142c098b7deaa8ccba2b09 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Tue, 14 Jul 2026 18:23:37 +1000
Subject: [PATCH] [orc-rt] Add ORC_RT_LOG_PUB_S for logging runtime strings.
ORC_RT_LOG requires its format to be a string literal, so the specifier for a
runtime C string cannot be written at the call site by hand -- and it differs
by backend: os_log redacts a plain "%s" argument to <private> unless it carries
a "%{public}s" annotation, which libc's printf does not understand.
Add ORC_RT_LOG_PUB_S, which expands to "%{public}s" on the os_log backend and
plain "%s" everywhere else. Call sites compose it into the format by literal
adjacency, so the format stays a single literal on every backend:
ORC_RT_LOG(Info, General, "resolved " ORC_RT_LOG_PUB_S, SymbolName);
LoggingTest covers the compile/format-check path (including os_log builds); the
orc-rt-log-check delivery test confirms os_log publishes the string rather than
redacting it to <private>.
---
orc-rt/include/orc-rt-c/Logging.h | 32 +++++++++++++++++++
.../regression/logging/os_log/delivery.test | 7 +++-
orc-rt/test/tools/orc-rt-log-check.cpp | 11 ++++++-
orc-rt/test/unit/LoggingTest.cpp | 5 +++
4 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/orc-rt/include/orc-rt-c/Logging.h b/orc-rt/include/orc-rt-c/Logging.h
index 60618d2f90a55..9f63e14a9a181 100644
--- a/orc-rt/include/orc-rt-c/Logging.h
+++ b/orc-rt/include/orc-rt-c/Logging.h
@@ -131,6 +131,38 @@ int orc_rt_log_formatCheck(const char *Fmt, ...) ORC_RT_C_FORMAT_PRINTF(1, 2);
((void)sizeof("" __VA_ARGS__, 0), \
ORC_RT_LOG_##Level(orc_rt_log_Category_##Category, __VA_ARGS__))
+/**
+ * \def ORC_RT_LOG_PUB_S
+ * Conversion specifier for publishing a runtime (non-literal) C string.
+ *
+ * Use this in place of a plain "%s" whenever you are logging a runtime string
+ * that should be readable in the log output: on os_log a "%s" argument defaults
+ * to private and is redacted in the system log, so ORC_RT_LOG_PUB_S is what
+ * actually publishes the bytes. Publishing is a privacy decision -- keep a
+ * plain "%s" (which stays private) for anything a sandboxed or privacy-
+ * sensitive deployment should not disclose, or do not log it at all. The printf
+ * backend has no public/private distinction and always prints the string
+ * regardless.
+ *
+ * ORC_RT_LOG requires Fmt to be a string literal, but the specifier for a
+ * runtime string differs by backend, so it cannot be written inline. This
+ * macro expands to a string literal that the surrounding format is expected to
+ * concatenate by literal adjacency, e.g.
+ *
+ * ORC_RT_LOG(Info, General, "resolved " ORC_RT_LOG_PUB_S, SymbolName);
+ *
+ * keeping Fmt a single literal on every backend.
+ *
+ * ORC_RT_LOG_PUB_S expands to plain "%s" for backends other than os_log:
+ * neither libc's vprintf nor the printf-style format checkers understand
+ * os_log's "%{public}s" syntax.
+ */
+#if ORC_RT_LOG_BACKEND == ORC_RT_LOG_BACKEND_OS_LOG
+#define ORC_RT_LOG_PUB_S "%{public}s"
+#else
+#define ORC_RT_LOG_PUB_S "%s"
+#endif
+
#if ORC_RT_LOG_BACKEND == ORC_RT_LOG_BACKEND_NONE
/* The none backend compiles every level out, regardless of ORC_RT_LOG_LEVEL. */
diff --git a/orc-rt/test/regression/logging/os_log/delivery.test b/orc-rt/test/regression/logging/os_log/delivery.test
index 9432738fda8cc..32740cfceda50 100644
--- a/orc-rt/test/regression/logging/os_log/delivery.test
+++ b/orc-rt/test/regression/logging/os_log/delivery.test
@@ -7,6 +7,11 @@
# the CHECK text, so the value reaches the pattern as [[uid]]). The record is
# emitted at ERROR level, which os_log persists, so `log show` sees it;
#
+# The record also carries a runtime string logged with ORC_RT_LOG_PUB_S. os_log
+# redacts a dynamic string to <private> unless it is published, so matching the
+# payload's contents (rather than <private>) confirms the public annotation
+# takes effect.
+#
# REQUIRES: os-log-show-tests
# RUN: orc-rt-log-check --uid %{orc-rt-log-uid}
# RUN: log show --predicate \
@@ -14,4 +19,4 @@
# RUN: --style compact --last 15s \
# RUN: | FileCheck -Duid=%{orc-rt-log-uid} %s
-# CHECK: delivery marker uid=[[uid]]
+# CHECK: delivery marker uid=[[uid]] payload=public-payload
diff --git a/orc-rt/test/tools/orc-rt-log-check.cpp b/orc-rt/test/tools/orc-rt-log-check.cpp
index e38854f20665f..6e17091ac38a7 100644
--- a/orc-rt/test/tools/orc-rt-log-check.cpp
+++ b/orc-rt/test/tools/orc-rt-log-check.cpp
@@ -108,7 +108,16 @@ int main(int argc, char *argv[]) {
// Emit one record whose payload carries the caller-supplied id, so a
// delivery test can match exactly its own record and not a stale one. The
// id is an integer (a %d scalar), which os_log shows unredacted.
- ORC_RT_LOG(Error, General, "delivery marker uid=%d", UID);
+ //
+ // The record also carries a runtime string logged via ORC_RT_LOG_PUB_S. On
+ // the os_log backend a dynamic string argument is redacted to <private>
+ // unless the public annotation is applied, so a delivery test can confirm
+ // the annotation publishes the string by matching its contents rather than
+ // <private>.
+ const char *PublicPayload = "public-payload";
+ ORC_RT_LOG(Error, General,
+ "delivery marker uid=%d payload=" ORC_RT_LOG_PUB_S, UID,
+ PublicPayload);
return 0;
}
diff --git a/orc-rt/test/unit/LoggingTest.cpp b/orc-rt/test/unit/LoggingTest.cpp
index 186f5982bee00..6cd192f4deb81 100644
--- a/orc-rt/test/unit/LoggingTest.cpp
+++ b/orc-rt/test/unit/LoggingTest.cpp
@@ -26,6 +26,11 @@ TEST(LoggingTest, CompilesAtEveryLevel) {
ORC_RT_LOG(Warning, General, "one arg: %d", 42);
ORC_RT_LOG(Info, General, "two args: %s = %d", "answer", 42);
ORC_RT_LOG(Debug, General, "wide arg: %llu", (unsigned long long)1 << 40);
+
+ // ORC_RT_LOG_PUB_S must concatenate into the literal format and type-check as
+ // a "%s" conversion against a runtime string on every backend.
+ const char *RuntimeStr = "runtime";
+ ORC_RT_LOG(Info, General, "public string: " ORC_RT_LOG_PUB_S, RuntimeStr);
SUCCEED();
}
More information about the llvm-commits
mailing list