https://github.com/jakos-sec updated 
https://github.com/llvm/llvm-project/pull/198292

>From 3b579b216685137c3823644dd58b49310d247c6b Mon Sep 17 00:00:00 2001
From: Jakob Koschel <[email protected]>
Date: Mon, 18 May 2026 13:01:12 +0000
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.7
---
 clang/docs/SafeStack.rst                      | 43 +++++++++++++++----
 clang/lib/Sema/SemaChecking.cpp               | 20 +++++++++
 .../test/Sema/safestack-deprecated-builtins.c | 17 ++++++++
 compiler-rt/include/CMakeLists.txt            |  1 +
 .../include/sanitizer/safestack_interface.h   | 35 +++++++++++++++
 compiler-rt/lib/safestack/CMakeLists.txt      |  1 +
 compiler-rt/lib/safestack/safestack.cpp       | 38 +++++++++++-----
 compiler-rt/test/safestack/sigaltstack.c      | 16 +++----
 8 files changed, 144 insertions(+), 27 deletions(-)
 create mode 100644 clang/test/Sema/safestack-deprecated-builtins.c
 create mode 100644 compiler-rt/include/sanitizer/safestack_interface.h

diff --git a/clang/docs/SafeStack.rst b/clang/docs/SafeStack.rst
index e347ae18b3506..edf8876931464 100644
--- a/clang/docs/SafeStack.rst
+++ b/clang/docs/SafeStack.rst
@@ -159,29 +159,56 @@ these variables, so extra care must be taken to manually 
ensure that all such
 accesses are safe. Furthermore, the addresses of such local variables should
 never be stored on the heap, as it would leak the location of the SafeStack.
 
+``sanitizer/safestack_interface.h``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To use the low-level API, include the header 
``<sanitizer/safestack_interface.h>``.
+
+``__safestack_get_unsafe_stack_ptr()``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This function returns current unsafe stack pointer of the current thread.
+
+``__safestack_get_unsafe_stack_bottom()``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This function returns a pointer to the bottom of the unsafe stack of the
+current thread.
+
+``__safestack_get_unsafe_stack_top()``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This function returns a pointer to the top of the unsafe stack of the
+current thread.
+
+
+
+Deprecated Builtins
+~~~~~~~~~~~~~~~~~~~
+
+The following builtins are still supported but are deprecated and will emit a
+warning. Use the corresponding functions from 
``<sanitizer/safestack_interface.h>``
+instead.
+
 ``__builtin___get_unsafe_stack_ptr()``
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-This builtin function returns current unsafe stack pointer of the current
-thread.
+Deprecated alias for ``__safestack_get_unsafe_stack_ptr()``.
 
 ``__builtin___get_unsafe_stack_bottom()``
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-This builtin function returns a pointer to the bottom of the unsafe stack of 
the
-current thread.
+Deprecated alias for ``__safestack_get_unsafe_stack_bottom()``.
 
 ``__builtin___get_unsafe_stack_top()``
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-This builtin function returns a pointer to the top of the unsafe stack of the
-current thread.
+Deprecated alias for ``__safestack_get_unsafe_stack_top()``.
 
 ``__builtin___get_unsafe_stack_start()``
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Deprecated: This builtin function is an alias for
-``__builtin___get_unsafe_stack_bottom()``.
+Deprecated alias for ``__safestack_get_unsafe_stack_bottom()``.
 
 Design
 ======
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 03091f2ba0cfe..b32032579aadd 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2915,6 +2915,26 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 
   FPOptions FPO;
   switch (BuiltinID) {
+  case Builtin::BI__builtin___get_unsafe_stack_start:
+    Diag(TheCall->getBeginLoc(), diag::warn_deprecated_builtin)
+        << Context.BuiltinInfo.getQuotedName(BuiltinID)
+        << "__safestack_get_unsafe_stack_bottom";
+    break;
+  case Builtin::BI__builtin___get_unsafe_stack_bottom:
+    Diag(TheCall->getBeginLoc(), diag::warn_deprecated_builtin)
+        << Context.BuiltinInfo.getQuotedName(BuiltinID)
+        << "__safestack_get_unsafe_stack_bottom";
+    break;
+  case Builtin::BI__builtin___get_unsafe_stack_top:
+    Diag(TheCall->getBeginLoc(), diag::warn_deprecated_builtin)
+        << Context.BuiltinInfo.getQuotedName(BuiltinID)
+        << "__safestack_get_unsafe_stack_top";
+    break;
+  case Builtin::BI__builtin___get_unsafe_stack_ptr:
+    Diag(TheCall->getBeginLoc(), diag::warn_deprecated_builtin)
+        << Context.BuiltinInfo.getQuotedName(BuiltinID)
+        << "__safestack_get_unsafe_stack_ptr";
+    break;
   case Builtin::BI__builtin_cpu_supports:
   case Builtin::BI__builtin_cpu_is:
     if (BuiltinCpu(*this, Context.getTargetInfo(), TheCall,
diff --git a/clang/test/Sema/safestack-deprecated-builtins.c 
b/clang/test/Sema/safestack-deprecated-builtins.c
new file mode 100644
index 0000000000000..c1818941b7d1c
--- /dev/null
+++ b/clang/test/Sema/safestack-deprecated-builtins.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -fsanitize=safe-stack
+
+void *test_bottom(void) {
+  return __builtin___get_unsafe_stack_bottom(); // expected-warning {{builtin 
'__builtin___get_unsafe_stack_bottom' is deprecated; use 
__safestack_get_unsafe_stack_bottom instead}}
+}
+
+void *test_top(void) {
+  return __builtin___get_unsafe_stack_top(); // expected-warning {{builtin 
'__builtin___get_unsafe_stack_top' is deprecated; use 
__safestack_get_unsafe_stack_top instead}}
+}
+
+void *test_ptr(void) {
+  return __builtin___get_unsafe_stack_ptr(); // expected-warning {{builtin 
'__builtin___get_unsafe_stack_ptr' is deprecated; use 
__safestack_get_unsafe_stack_ptr instead}}
+}
+
+void *test_start(void) {
+  return __builtin___get_unsafe_stack_start(); // expected-warning {{builtin 
'__builtin___get_unsafe_stack_start' is deprecated; use 
__safestack_get_unsafe_stack_bottom instead}}
+}
diff --git a/compiler-rt/include/CMakeLists.txt 
b/compiler-rt/include/CMakeLists.txt
index 8443e309d1e95..eb998478b081b 100644
--- a/compiler-rt/include/CMakeLists.txt
+++ b/compiler-rt/include/CMakeLists.txt
@@ -11,6 +11,7 @@ if (COMPILER_RT_BUILD_SANITIZERS)
     sanitizer/msan_interface.h
     sanitizer/netbsd_syscall_hooks.h
     sanitizer/rtsan_interface.h
+    sanitizer/safestack_interface.h
     sanitizer/scudo_interface.h
     sanitizer/tsan_interface.h
     sanitizer/tsan_interface_atomic.h
diff --git a/compiler-rt/include/sanitizer/safestack_interface.h 
b/compiler-rt/include/sanitizer/safestack_interface.h
new file mode 100644
index 0000000000000..bab74b355d10a
--- /dev/null
+++ b/compiler-rt/include/sanitizer/safestack_interface.h
@@ -0,0 +1,35 @@
+//===-- sanitizer/safestack_interface.h -------------------------*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of SafeStack.
+//
+// Public interface header.
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_SAFESTACK_INTERFACE_H
+#define SANITIZER_SAFESTACK_INTERFACE_H
+
+#include <sanitizer/common_interface_defs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// Returns the current unsafe stack pointer of the current thread.
+void SANITIZER_CDECL *__safestack_get_unsafe_stack_ptr(void);
+
+/// Returns a pointer to the bottom of the unsafe stack of the current thread.
+void SANITIZER_CDECL *__safestack_get_unsafe_stack_bottom(void);
+
+/// Returns a pointer to the top of the unsafe stack of the current thread.
+void SANITIZER_CDECL *__safestack_get_unsafe_stack_top(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // SANITIZER_SAFESTACK_INTERFACE_H
diff --git a/compiler-rt/lib/safestack/CMakeLists.txt 
b/compiler-rt/lib/safestack/CMakeLists.txt
index 4cff95f546931..39a4e8294f359 100644
--- a/compiler-rt/lib/safestack/CMakeLists.txt
+++ b/compiler-rt/lib/safestack/CMakeLists.txt
@@ -5,6 +5,7 @@ set(SAFESTACK_SOURCES
   )
 
 include_directories(..)
+include_directories(../../include)
 
 set(SAFESTACK_CFLAGS ${SANITIZER_COMMON_CFLAGS})
 
diff --git a/compiler-rt/lib/safestack/safestack.cpp 
b/compiler-rt/lib/safestack/safestack.cpp
index ec8c1dd6c8acb..ab0d0be72b53c 100644
--- a/compiler-rt/lib/safestack/safestack.cpp
+++ b/compiler-rt/lib/safestack/safestack.cpp
@@ -23,6 +23,7 @@
 #include "safestack_platform.h"
 #include "safestack_util.h"
 #include "sanitizer_common/sanitizer_internal_defs.h"
+#include "sanitizer/safestack_interface.h"
 
 // interception.h drags in sanitizer_redefine_builtins.h, which in turn
 // creates references to __sanitizer_internal_memcpy etc.  The interceptors
@@ -338,22 +339,39 @@ __attribute__((section(".preinit_array"),
 }
 #endif
 
-extern "C"
-    __attribute__((visibility("default"))) void *__get_unsafe_stack_bottom() {
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void *__safestack_get_unsafe_stack_bottom() {
   return unsafe_stack_start;
 }
 
-extern "C"
-    __attribute__((visibility("default"))) void *__get_unsafe_stack_top() {
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void *__safestack_get_unsafe_stack_top() {
   return (char*)unsafe_stack_start + unsafe_stack_size;
 }
 
-extern "C"
-    __attribute__((visibility("default"))) void *__get_unsafe_stack_start() {
-  return unsafe_stack_start;
-}
 
-extern "C"
-    __attribute__((visibility("default"))) void *__get_unsafe_stack_ptr() {
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void *__safestack_get_unsafe_stack_ptr() {
   return __safestack_unsafe_stack_ptr;
 }
+
+// Compatibility aliases
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void *__get_unsafe_stack_bottom() {
+  return __safestack_get_unsafe_stack_bottom();
+}
+
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void *__get_unsafe_stack_top() {
+  return __safestack_get_unsafe_stack_top();
+}
+
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void *__get_unsafe_stack_start() {
+  return __safestack_get_unsafe_stack_bottom();
+}
+
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void *__get_unsafe_stack_ptr() {
+  return __safestack_get_unsafe_stack_ptr();
+}
diff --git a/compiler-rt/test/safestack/sigaltstack.c 
b/compiler-rt/test/safestack/sigaltstack.c
index a6c77009874f6..395228b167a43 100644
--- a/compiler-rt/test/safestack/sigaltstack.c
+++ b/compiler-rt/test/safestack/sigaltstack.c
@@ -15,22 +15,20 @@
 // Test that safe stack works with sigaltstack.
 int puts(const char *);
 
-extern void *__get_unsafe_stack_ptr();
-extern void *__get_unsafe_stack_top();
-extern void *__get_unsafe_stack_bottom();
+#include <sanitizer/safestack_interface.h>
 
 __thread int signal_handlers_called = 0;
 
 void signal_handler(int signo) {
   signal_handlers_called += 1;
-  assert(__get_unsafe_stack_ptr() <= __get_unsafe_stack_top() &&
-         __get_unsafe_stack_ptr() >= __get_unsafe_stack_bottom());
+  assert(__safestack_get_unsafe_stack_ptr() <= 
__safestack_get_unsafe_stack_top() &&
+         __safestack_get_unsafe_stack_ptr() >= 
__safestack_get_unsafe_stack_bottom());
 }
 
 void signal_sigaction(int signo, siginfo_t *si, void *uc) {
   signal_handlers_called += 1;
-  assert(__get_unsafe_stack_ptr() <= __get_unsafe_stack_top() &&
-         __get_unsafe_stack_ptr() >= __get_unsafe_stack_bottom());
+  assert(__safestack_get_unsafe_stack_ptr() <= 
__safestack_get_unsafe_stack_top() &&
+         __safestack_get_unsafe_stack_ptr() >= 
__safestack_get_unsafe_stack_bottom());
 }
 
 void *t1_start(void *ptr) {
@@ -113,8 +111,8 @@ int main() {
   raise(SIGUSR2);
 
   // Check that unsafe stack is set to the normal unsafe stack.
-  assert(__get_unsafe_stack_ptr() <= __get_unsafe_stack_top() &&
-         __get_unsafe_stack_ptr() >= __get_unsafe_stack_bottom());
+  assert(__safestack_get_unsafe_stack_ptr() <= 
__safestack_get_unsafe_stack_top() &&
+         __safestack_get_unsafe_stack_ptr() >= 
__safestack_get_unsafe_stack_bottom());
 
   assert(signal_handlers_called == 4);
 

>From e7afa9ccfe1b58b198e7e2b7127c2d1dda316a20 Mon Sep 17 00:00:00 2001
From: Jakob Koschel <[email protected]>
Date: Mon, 18 May 2026 13:02:09 +0000
Subject: [PATCH 2/2] fix clang-format

Created using spr 1.3.7
---
 compiler-rt/lib/safestack/safestack.cpp  | 27 ++++++++++--------------
 compiler-rt/test/safestack/sigaltstack.c | 18 ++++++++++------
 2 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/compiler-rt/lib/safestack/safestack.cpp 
b/compiler-rt/lib/safestack/safestack.cpp
index ab0d0be72b53c..01f95109c976b 100644
--- a/compiler-rt/lib/safestack/safestack.cpp
+++ b/compiler-rt/lib/safestack/safestack.cpp
@@ -22,8 +22,8 @@
 #include "interception/interception.h"
 #include "safestack_platform.h"
 #include "safestack_util.h"
-#include "sanitizer_common/sanitizer_internal_defs.h"
 #include "sanitizer/safestack_interface.h"
+#include "sanitizer_common/sanitizer_internal_defs.h"
 
 // interception.h drags in sanitizer_redefine_builtins.h, which in turn
 // creates references to __sanitizer_internal_memcpy etc.  The interceptors
@@ -339,39 +339,34 @@ __attribute__((section(".preinit_array"),
 }
 #endif
 
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void *__safestack_get_unsafe_stack_bottom() {
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void*
+__safestack_get_unsafe_stack_bottom() {
   return unsafe_stack_start;
 }
 
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void *__safestack_get_unsafe_stack_top() {
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void*
+__safestack_get_unsafe_stack_top() {
   return (char*)unsafe_stack_start + unsafe_stack_size;
 }
 
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void *__safestack_get_unsafe_stack_ptr() {
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void*
+__safestack_get_unsafe_stack_ptr() {
   return __safestack_unsafe_stack_ptr;
 }
 
 // Compatibility aliases
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void *__get_unsafe_stack_bottom() {
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void* __get_unsafe_stack_bottom() {
   return __safestack_get_unsafe_stack_bottom();
 }
 
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void *__get_unsafe_stack_top() {
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void* __get_unsafe_stack_top() {
   return __safestack_get_unsafe_stack_top();
 }
 
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void *__get_unsafe_stack_start() {
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void* __get_unsafe_stack_start() {
   return __safestack_get_unsafe_stack_bottom();
 }
 
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void *__get_unsafe_stack_ptr() {
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void* __get_unsafe_stack_ptr() {
   return __safestack_get_unsafe_stack_ptr();
 }
diff --git a/compiler-rt/test/safestack/sigaltstack.c 
b/compiler-rt/test/safestack/sigaltstack.c
index 395228b167a43..3c9fd61acff91 100644
--- a/compiler-rt/test/safestack/sigaltstack.c
+++ b/compiler-rt/test/safestack/sigaltstack.c
@@ -21,14 +21,18 @@ __thread int signal_handlers_called = 0;
 
 void signal_handler(int signo) {
   signal_handlers_called += 1;
-  assert(__safestack_get_unsafe_stack_ptr() <= 
__safestack_get_unsafe_stack_top() &&
-         __safestack_get_unsafe_stack_ptr() >= 
__safestack_get_unsafe_stack_bottom());
+  assert(__safestack_get_unsafe_stack_ptr() <=
+             __safestack_get_unsafe_stack_top() &&
+         __safestack_get_unsafe_stack_ptr() >=
+             __safestack_get_unsafe_stack_bottom());
 }
 
 void signal_sigaction(int signo, siginfo_t *si, void *uc) {
   signal_handlers_called += 1;
-  assert(__safestack_get_unsafe_stack_ptr() <= 
__safestack_get_unsafe_stack_top() &&
-         __safestack_get_unsafe_stack_ptr() >= 
__safestack_get_unsafe_stack_bottom());
+  assert(__safestack_get_unsafe_stack_ptr() <=
+             __safestack_get_unsafe_stack_top() &&
+         __safestack_get_unsafe_stack_ptr() >=
+             __safestack_get_unsafe_stack_bottom());
 }
 
 void *t1_start(void *ptr) {
@@ -111,8 +115,10 @@ int main() {
   raise(SIGUSR2);
 
   // Check that unsafe stack is set to the normal unsafe stack.
-  assert(__safestack_get_unsafe_stack_ptr() <= 
__safestack_get_unsafe_stack_top() &&
-         __safestack_get_unsafe_stack_ptr() >= 
__safestack_get_unsafe_stack_bottom());
+  assert(__safestack_get_unsafe_stack_ptr() <=
+             __safestack_get_unsafe_stack_top() &&
+         __safestack_get_unsafe_stack_ptr() >=
+             __safestack_get_unsafe_stack_bottom());
 
   assert(signal_handlers_called == 4);
 

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

Reply via email to