[llvm] [SafeStack] Fix logic checking for incompatible llvm.gcroot intrinsics (PR #78937)

Nicholas Mosier via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 21 21:10:14 PST 2024


https://github.com/nmosier created https://github.com/llvm/llvm-project/pull/78937

This patch fixes a logic bug that prevented SafeStack from detecting and reporting llvm.gcroot intrinsics, which are not compatible with SafeStack.

>From 0bc7c4cf9b9c5e74a0a67bc03a4c511238ca9d45 Mon Sep 17 00:00:00 2001
From: Nicholas Mosier <nmosier at stanford.edu>
Date: Mon, 22 Jan 2024 05:04:49 +0000
Subject: [PATCH] [SafeStack] Fix logic checking for incompatible llvm.gcroot
 intrinsics

This patch fixes a logic bug that prevented SafeStack from detecting
and reporting llvm.gcroot intrinsics, which are not compatible with
SafeStack.
---
 llvm/lib/CodeGen/SafeStack.cpp               |  8 ++++----
 llvm/test/Transforms/SafeStack/X86/gcroot.ll | 15 +++++++++++++++
 2 files changed, 19 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/Transforms/SafeStack/X86/gcroot.ll

diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp
index 0a26247a4d1659..a508cd9facb917 100644
--- a/llvm/lib/CodeGen/SafeStack.cpp
+++ b/llvm/lib/CodeGen/SafeStack.cpp
@@ -400,6 +400,10 @@ void SafeStack::findInsts(Function &F,
         Returns.push_back(CI);
       else
         Returns.push_back(RI);
+    } else if (auto II = dyn_cast<IntrinsicInst>(&I)) {
+      if (II->getIntrinsicID() == Intrinsic::gcroot)
+        report_fatal_error(
+            "gcroot intrinsic not compatible with safestack attribute");
     } else if (auto CI = dyn_cast<CallInst>(&I)) {
       // setjmps require stack restore.
       if (CI->getCalledFunction() && CI->canReturnTwice())
@@ -407,10 +411,6 @@ void SafeStack::findInsts(Function &F,
     } else if (auto LP = dyn_cast<LandingPadInst>(&I)) {
       // Exception landing pads require stack restore.
       StackRestorePoints.push_back(LP);
-    } else if (auto II = dyn_cast<IntrinsicInst>(&I)) {
-      if (II->getIntrinsicID() == Intrinsic::gcroot)
-        report_fatal_error(
-            "gcroot intrinsic not compatible with safestack attribute");
     }
   }
   for (Argument &Arg : F.args()) {
diff --git a/llvm/test/Transforms/SafeStack/X86/gcroot.ll b/llvm/test/Transforms/SafeStack/X86/gcroot.ll
new file mode 100644
index 00000000000000..bc8bacb0c16b62
--- /dev/null
+++ b/llvm/test/Transforms/SafeStack/X86/gcroot.ll
@@ -0,0 +1,15 @@
+; RUN: not --crash opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not --crash opt -safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not --crash opt -passes=safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not --crash opt -passes=safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o /dev/null 2>&1 | FileCheck %s
+
+define void @foo()  nounwind uwtable safestack gc "shadow-stack" {
+  %1 = alloca ptr, align 4
+  call void @bar(ptr %1)
+  ; CHECK: LLVM ERROR: gcroot intrinsic not compatible with safestack attribute
+  call void @llvm.gcroot(ptr %1, ptr null)
+  ret void
+}
+
+declare void @bar(ptr)
+declare void @llvm.gcroot(ptr, ptr)



More information about the llvm-commits mailing list