[llvm] 99e53cb - [llvm][StackProtector] Add noreturn to __stack_chk_fail call (#143976)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 16 15:47:47 PDT 2025
Author: PiJoules
Date: 2025-06-16T15:47:43-07:00
New Revision: 99e53cb4139eda491f97cb33ee42ea424d352200
URL: https://github.com/llvm/llvm-project/commit/99e53cb4139eda491f97cb33ee42ea424d352200
DIFF: https://github.com/llvm/llvm-project/commit/99e53cb4139eda491f97cb33ee42ea424d352200.diff
LOG: [llvm][StackProtector] Add noreturn to __stack_chk_fail call (#143976)
It's possible for __stack_chk_fail to be an alias when using CrossDSOCFI
since it will make a jump table entry for this function and replace it
with an alias. StackProtector can crash since it always expects this to
be a regular function. Instead add the noreturn attribute to the call.
Added:
llvm/test/Transforms/StackProtector/cross-dso-cfi-stack-chk-fail.ll
llvm/test/Transforms/StackProtector/stack-chk-fail-alias.ll
Modified:
llvm/lib/CodeGen/StackProtector.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index 5f866eea7d4e7..dda392d38b27a 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -725,8 +725,8 @@ BasicBlock *CreateFailBB(Function *F, const Triple &Trip) {
StackChkFail =
M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context));
}
- cast<Function>(StackChkFail.getCallee())->addFnAttr(Attribute::NoReturn);
- B.CreateCall(StackChkFail, Args);
+ CallInst *Call = B.CreateCall(StackChkFail, Args);
+ Call->addFnAttr(Attribute::NoReturn);
B.CreateUnreachable();
return FailBB;
}
diff --git a/llvm/test/Transforms/StackProtector/cross-dso-cfi-stack-chk-fail.ll b/llvm/test/Transforms/StackProtector/cross-dso-cfi-stack-chk-fail.ll
new file mode 100644
index 0000000000000..af03039813a2e
--- /dev/null
+++ b/llvm/test/Transforms/StackProtector/cross-dso-cfi-stack-chk-fail.ll
@@ -0,0 +1,33 @@
+;; This is a minimal reproducer that caused StackProtector to crash with a bad cast when
+;; CrossDSOCFI is used. This test just needs to not crash.
+; RUN: opt -mtriple=x86_64-pc-linux-gnu %s -passes=lowertypetests,cross-dso-cfi,stack-protector
+
+define hidden void @__stack_chk_fail() !type !1{
+ unreachable
+}
+
+define void @store_captures() sspstrong {
+entry:
+ %a = alloca i32, align 4
+ %j = alloca ptr, align 8
+ store ptr %a, ptr %j, align 8
+ ret void
+}
+
+define void @func(ptr %0) {
+entry:
+ %1 = call i1 @llvm.type.test(ptr %0, metadata !"typeid")
+ br i1 %1, label %cont, label %trap
+
+trap: ; preds = %entry
+ call void @llvm.trap()
+ unreachable
+
+cont: ; preds = %entry
+ call void %0()
+ ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 4, !"Cross-DSO CFI", i32 1}
+!1 = !{i64 0, !"typeid"}
diff --git a/llvm/test/Transforms/StackProtector/stack-chk-fail-alias.ll b/llvm/test/Transforms/StackProtector/stack-chk-fail-alias.ll
new file mode 100644
index 0000000000000..ab0a6e3f455e7
--- /dev/null
+++ b/llvm/test/Transforms/StackProtector/stack-chk-fail-alias.ll
@@ -0,0 +1,21 @@
+;; __stack_chk_fail should have the noreturn attr even if it is an alias
+; RUN: opt -mtriple=x86_64-pc-linux-gnu %s -passes=stack-protector -S | FileCheck %s
+
+define hidden void @__stack_chk_fail_impl() {
+ unreachable
+}
+
+ at __stack_chk_fail = hidden alias void (), ptr @__stack_chk_fail_impl
+
+; CHECK-LABEL: @store_captures(
+; CHECK: CallStackCheckFailBlk:
+; CHECK-NEXT: call void @__stack_chk_fail() [[ATTRS:#.*]]
+define void @store_captures() sspstrong {
+entry:
+ %a = alloca i32, align 4
+ %j = alloca ptr, align 8
+ store ptr %a, ptr %j, align 8
+ ret void
+}
+
+; CHECK: attributes [[ATTRS]] = { noreturn }
More information about the llvm-commits
mailing list