[clang] [llvm] [CodeGen][Clang] Add -fstack-protector-layout-only (PR #231651)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 13 13:53:11 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
Author: amosher-nvidia
<details>
<summary>Changes</summary>
Add a way to apply only the changes to the stack frame layout that are made when stack protectors are enabled, without actually inserting a stack protector.
This is useful on architectures which have hardware features that can act like stack protectors like Zicfiss on RISC-V, where any return addresses spilled to the stack effectively act as stack cookies.
Changes to LLVM:
Add a new "stack-protector-layout-only" function attribute. When specified, the StackProtector pass still identifies the objects that are likely to be overflowed, and adjusts the stack frame layout accordingly, but does not insert a stack protector.
Add a new MachineFrameInfo flag, stackProtectorLayoutOnly. It tells PrologEpilogInserter and LocalStackSlotAllocation to apply the stack protector's frame layout changes for those objects although no stack protector object exists.
Changes to Clang:
Add a new flag -fstack-protector-layout-only which adds the layout-only attribute to every function that gets a stack protector attribute. At a minimum -fstack-protector is enabled so that the layout changes can be made; if stack protection would otherwise be off, by default or via an explicit -fno-stack-protector, a warning is emitted.
---
Patch is 58.51 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/231651.diff
31 Files Affected:
- (modified) clang/docs/ReleaseNotes.md (+6)
- (modified) clang/docs/UsersManual.md (+11)
- (modified) clang/include/clang/Basic/CodeGenOptions.def (+1)
- (modified) clang/include/clang/Options/Options.td (+7)
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+2)
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+19)
- (modified) clang/test/CodeGen/stack-protector.c (+9)
- (modified) clang/test/Driver/stack-protector.c (+32)
- (modified) llvm/docs/LangRef.md (+9)
- (modified) llvm/docs/ReleaseNotes.md (+8)
- (modified) llvm/include/llvm/CodeGen/MIRYamlMapping.h (+4)
- (modified) llvm/include/llvm/CodeGen/MachineFrameInfo.h (+11)
- (modified) llvm/include/llvm/CodeGen/StackProtector.h (+3)
- (modified) llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (+2-1)
- (modified) llvm/lib/CodeGen/LocalStackSlotAllocation.cpp (+17-14)
- (modified) llvm/lib/CodeGen/MIRParser/MIRParser.cpp (+1)
- (modified) llvm/lib/CodeGen/MIRPrinter.cpp (+1)
- (modified) llvm/lib/CodeGen/PrologEpilogInserter.cpp (+24-19)
- (modified) llvm/lib/CodeGen/StackProtector.cpp (+32)
- (modified) llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (+2-1)
- (added) llvm/test/CodeGen/AArch64/stack-protector-layout-only-codegen.ll (+140)
- (added) llvm/test/CodeGen/AArch64/stack-protector-layout-only.ll (+93)
- (modified) llvm/test/CodeGen/MIR/Generic/frame-info.mir (+3)
- (added) llvm/test/CodeGen/RISCV/stack-protector-layout-only-codegen.ll (+120)
- (added) llvm/test/CodeGen/RISCV/stack-protector-layout-only.ll (+94)
- (added) llvm/test/CodeGen/X86/stack-protector-layout-only-funclet.ll (+37)
- (added) llvm/test/CodeGen/X86/stack-protector-layout-only.ll (+94)
- (added) llvm/test/Transforms/Inline/inline_ssp_layout_only.ll (+86)
- (added) llvm/test/Transforms/StackProtector/layout-only-no-analysis.ll (+14)
- (added) llvm/test/Transforms/StackProtector/layout-only-no-protector.ll (+54)
- (modified) llvm/tools/llvm-reduce/ReducerWorkItem.cpp (+2)
``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 1dc1764978ea2..23f30097f5985 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -290,6 +290,12 @@ features cannot lower the translation-unit ABI level;
- New option `-fdefined-pointer-subtraction` added to preserve stable semantics
when subtracting pointers to unrelated objects.
+- Added `-fstack-protector-layout-only`. When specified, changes to the layout
+ of a stack frame that occur when `-fstack-protector` is specified are applied
+ but a stack protector is not actually inserted. This allows targets that have
+ features that can act as pseudo-stack-protectors, like RISC-V's shadow stack,
+ to benefit from the protection added by reordering stack variables.
+
- Added `--print-cxx-stdlib` and `--print-cxx-stdlib-include-dirs` to print
the C++ standard library selected by the driver and the include directories
added for it.
diff --git a/clang/docs/UsersManual.md b/clang/docs/UsersManual.md
index 96d1c4e009c71..a310890a58fcb 100644
--- a/clang/docs/UsersManual.md
+++ b/clang/docs/UsersManual.md
@@ -3037,6 +3037,17 @@ at block entry, which is more expensive and no more useful for the jumps this
feature exists to guard against. Clang applies the C++ rule in both languages.
:::
+:::{option} -f[no-]stack-protector-layout-only
+
+When specified, stack protectors will not be inserted, but stack variables will
+continue to be rearranged as if they were. This allows targets that have
+features that can act as pseudo-stack-protectors, like RISC-V's shadow stack,
+to benefit from the protection added by reordering stack variables.
+
+This option depends on at least `-fstack-protector`, so it will be overridden to
+being enabled with a warning, even if `-fno-stack-protector` is given.
+:::
+
(strict_aliasing)=
(strict-aliasing)=
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 10d9a4e3a6a82..fbe34acf667e5 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -167,6 +167,7 @@ CODEGENOPT(CallFEntry , 1, 0, Benign) ///< Set when -mfentry is enabled.
CODEGENOPT(MNopMCount , 1, 0, Benign) ///< Set when -mnop-mcount is enabled.
CODEGENOPT(RecordMCount , 1, 0, Benign) ///< Set when -mrecord-mcount is enabled.
CODEGENOPT(StackProtectorGuardRecord, 1, 0, Benign) ///< Set when -mstack-protector-guard-record is enabled.
+CODEGENOPT(StackProtectorLayoutOnly, 1, 0, Benign) ///< Set when -fstack-protector-layout-only is enabled.
CODEGENOPT(PackedStack , 1, 0, Benign) ///< Set when -mpacked-stack is enabled.
CODEGENOPT(LessPreciseFPMAD , 1, 0, Benign) ///< Enable less precise MAD instructions to
///< be generated.
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 1adc5f8399e4b..7d0ea985436c5 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -4626,6 +4626,13 @@ defm split_stack : BoolFOption<"split-stack",
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use segmented stack">>;
def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>,
HelpText<"Enable stack protectors for all functions">;
+defm stack_protector_layout_only : BoolFOption<"stack-protector-layout-only",
+ CodeGenOpts<"StackProtectorLayoutOnly">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Apply only the stack frame layout changes as part of stack protection, "
+ "without inserting stack protectors">,
+ NegFlag<SetFalse, [], [ClangOption],
+ "Insert stack protectors when stack protection is enabled">>;
defm stack_clash_protection : BoolFOption<"stack-clash-protection",
CodeGenOpts<"StackClashProtector">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index bce2106a74988..a7caf8abf7e04 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3186,6 +3186,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
if (std::optional<llvm::Attribute::AttrKind> Attr =
StackProtectorAttribute(D)) {
B.addAttribute(*Attr);
+ if (CodeGenOpts.StackProtectorLayoutOnly)
+ B.addAttribute("stack-protector-layout-only");
}
if (!D) {
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index fb6effb65d71f..20adb4d67f30f 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3673,10 +3673,29 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
StackProtectorLevel = DefaultStackProtectorLevel;
}
+ bool LayoutOnly = false;
+ if (Arg *A = Args.getLastArg(options::OPT_fstack_protector_layout_only,
+ options::OPT_fno_stack_protector_layout_only)) {
+ LayoutOnly =
+ A->getOption().matches(options::OPT_fstack_protector_layout_only);
+ if (LayoutOnly && EffectiveTriple.isBPF()) {
+ D.Diag(diag::warn_drv_unsupported_option_for_target)
+ << A->getSpelling() << EffectiveTriple.getTriple();
+ LayoutOnly = false;
+ }
+ if (LayoutOnly && StackProtectorLevel == LangOptions::SSPOff) {
+ D.Diag(diag::warn_drv_overriding_option)
+ << "-fno-stack-protector" << A->getSpelling();
+ StackProtectorLevel = LangOptions::SSPOn;
+ }
+ }
+
if (StackProtectorLevel) {
CmdArgs.push_back("-stack-protector");
CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel)));
}
+ if (LayoutOnly)
+ CmdArgs.push_back("-fstack-protector-layout-only");
// --param ssp-buffer-size=
for (const Arg *A : Args.filtered(options::OPT__param)) {
diff --git a/clang/test/CodeGen/stack-protector.c b/clang/test/CodeGen/stack-protector.c
index 9b93f775ffe79..b8996c02ff33b 100644
--- a/clang/test/CodeGen/stack-protector.c
+++ b/clang/test/CodeGen/stack-protector.c
@@ -9,6 +9,11 @@
// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=safe-stack -stack-protector 2 | FileCheck -check-prefix=DEF -check-prefix=SAFESTACK-SSPSTRONG %s
// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=safe-stack -stack-protector 3 | FileCheck -check-prefix=DEF -check-prefix=SAFESTACK-SSPREQ %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 0 -fstack-protector-layout-only | FileCheck -check-prefix=DEF -check-prefix=NOSSP -check-prefix=NO-LAYOUT-ONLY %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 1 -fstack-protector-layout-only | FileCheck -check-prefix=DEF -check-prefix=SSP -check-prefix=LAYOUT-ONLY %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 2 -fstack-protector-layout-only | FileCheck -check-prefix=DEF -check-prefix=SSPSTRONG -check-prefix=LAYOUT-ONLY %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 3 -fstack-protector-layout-only | FileCheck -check-prefix=DEF -check-prefix=SSPREQ -check-prefix=LAYOUT-ONLY %s
+
typedef __SIZE_TYPE__ size_t;
int printf(const char * _Format, ...);
@@ -34,6 +39,7 @@ void test2(const char *msg) {
// SSP: attributes #[[A]] = {{.*}} ssp{{ }}
// SSPSTRONG: attributes #[[A]] = {{.*}} sspstrong
// SSPREQ: attributes #[[A]] = {{.*}} sspreq
+// LAYOUT-ONLY-SAME: "stack-protector-layout-only"
// SAFESTACK-NOSSP: attributes #[[A]] = {{.*}} safestack
// SAFESTACK-NOSSP-NOT: ssp
@@ -53,3 +59,6 @@ void test2(const char *msg) {
// SAFESTACK-SSPSTRONG-NOT: attributes #[[B]] = {{.*}} safestack sspstrong
// SAFESTACK-SSPREQ: attributes #[[B]] = {{.*}} safestack
// SAFESTACK-SSPREQ-NOT: attributes #[[B]] = {{.*}} safestack sspreq
+
+// LAYOUT-ONLY-NOT: attributes #[[B]] = {{.*}} "stack-protector-layout-only"
+// NO-LAYOUT-ONLY-NOT: "stack-protector-layout-only"
diff --git a/clang/test/Driver/stack-protector.c b/clang/test/Driver/stack-protector.c
index e082b3361d058..f258ada07d162 100644
--- a/clang/test/Driver/stack-protector.c
+++ b/clang/test/Driver/stack-protector.c
@@ -55,3 +55,35 @@
// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacos-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX_10_6_KERNEL
// SSP_MACOSX_10_6_KERNEL: "-stack-protector" "1"
+// Test -fstack-protector-layout-only with the different stack protector levels
+
+// RUN: %clang --target=x86_64-unknown-linux-gnu -fstack-protector-layout-only -### %s 2>&1 | FileCheck %s -check-prefix=SSP-LAYOUT-ONLY
+// SSP-LAYOUT-ONLY: warning: overriding '-fno-stack-protector' option with '-fstack-protector-layout-only'
+// SSP-LAYOUT-ONLY: "-stack-protector" "1" "-fstack-protector-layout-only"
+
+// RUN: %clang --target=x86_64-unknown-linux-gnu -fno-stack-protector -fstack-protector-layout-only -### %s 2>&1 | FileCheck %s -check-prefix=SSP-LAYOUT-ONLY-NO-SSP
+// RUN: %clang --target=x86_64-unknown-linux-gnu -fstack-protector-layout-only -fno-stack-protector -### %s 2>&1 | FileCheck %s -check-prefix=SSP-LAYOUT-ONLY-NO-SSP
+// SSP-LAYOUT-ONLY-NO-SSP: warning: overriding '-fno-stack-protector' option with '-fstack-protector-layout-only'
+// SSP-LAYOUT-ONLY-NO-SSP: "-stack-protector" "1" "-fstack-protector-layout-only"
+
+// RUN: %clang --target=x86_64-unknown-linux-gnu -fstack-protector-layout-only -fstack-protector-strong -### %s 2>&1 | FileCheck %s -check-prefix=SSP-LAYOUT-ONLY-STRONG
+// SSP-LAYOUT-ONLY-STRONG-NOT: warning:
+// SSP-LAYOUT-ONLY-STRONG: "-stack-protector" "2" "-fstack-protector-layout-only"
+
+// RUN: %clang --target=x86_64-unknown-linux-gnu -fstack-protector-all -fstack-protector-layout-only -### %s 2>&1 | FileCheck %s -check-prefix=SSP-LAYOUT-ONLY-ALL
+// SSP-LAYOUT-ONLY-ALL-NOT: warning:
+// SSP-LAYOUT-ONLY-ALL: "-stack-protector" "3" "-fstack-protector-layout-only"
+
+// RUN: %clang --target=i386-pc-openbsd -fstack-protector-layout-only -### %s 2>&1 | FileCheck %s -check-prefix=SSP-LAYOUT-ONLY-OPENBSD
+// SSP-LAYOUT-ONLY-OPENBSD-NOT: warning:
+// SSP-LAYOUT-ONLY-OPENBSD: "-stack-protector" "2" "-fstack-protector-layout-only"
+
+// RUN: %clang --target=x86_64-unknown-linux-gnu -fstack-protector-layout-only -fno-stack-protector-layout-only -### %s 2>&1 | FileCheck %s -check-prefix=NO-SSP-LAYOUT-ONLY
+// NO-SSP-LAYOUT-ONLY-NOT: "-stack-protector"
+// NO-SSP-LAYOUT-ONLY-NOT: "-fstack-protector-layout-only"
+
+// RUN: %clang --target=bpf -fstack-protector-layout-only -### %s 2>&1 | FileCheck %s -check-prefix=SSP-LAYOUT-ONLY-BPF
+// SSP-LAYOUT-ONLY-BPF: warning: ignoring '-fstack-protector-layout-only' option as it is not currently supported for target 'bpf'
+// SSP-LAYOUT-ONLY-BPF-NOT: overriding
+// SSP-LAYOUT-ONLY-BPF-NOT: "-stack-protector"
+// SSP-LAYOUT-ONLY-BPF-NOT: "-fstack-protector-layout-only"
diff --git a/llvm/docs/LangRef.md b/llvm/docs/LangRef.md
index 84af4a727c223..82ddd5c6db533 100644
--- a/llvm/docs/LangRef.md
+++ b/llvm/docs/LangRef.md
@@ -2841,6 +2841,15 @@ fn -> other_fn -> other_fn ; fn is norecurse
function which has an `ssp` or `sspstrong` attribute, the calling
function's attribute will be upgraded to `sspreq`.
+`"stack-protector-layout-only"`
+: This attribute is only meaningful in conjunction with one of the stack
+ protector attributes above. It indicates that only the changes to the
+ stack frame layout that are made for a stack protector are applied,
+ and no stack protectors are actually inserted.
+
+ If a function with this attribute is inlined into a calling function, the
+ attribute will not be added to the calling function.
+
(strictfp)=
`strictfp`
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index cec21851f0d76..90c76bb84e62d 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -172,6 +172,10 @@ Makes programs 10x faster by doing Special New Thing.
* Added the `bitinsert` and `bitextract` instructions for bit-range
manipulation on byte type values.
+* Added the `"stack-protector-layout-only"` attribute. When specified, the
+ `ssp`/`sspstrong`/`sspreq` attributes still make changes to the layout of the
+ stack frame, but do not actually insert any stack protectors.
+
### Changes to LLVM infrastructure
* Removed `TargetOptions::FloatABIType`. The soft float ABI should be
@@ -387,6 +391,10 @@ Makes programs 10x faster by doing Special New Thing.
### Changes to the CodeGen infrastructure
+* `MachineFrameInfo` gained a `stackProtectorLayoutOnly` flag. It tells the
+ prolog/epilog inserter and local stack slot allocation to lay out the stack
+ objects as if the function had a stack protector, even though it does not.
+
* Fixed a crash
([#214750](https://github.com/llvm/llvm-project/issues/214750)) when
compiling a function containing a static alloca of `(size_t)-1` bytes, whose
diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index ab1c91d9f0de5..2d09ad29aedac 100644
--- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -736,6 +736,7 @@ struct MachineFrameInfo {
bool HasCalls = false;
FramePointerKind FramePointerPolicy = FramePointerKind::None;
StringValue StackProtector;
+ bool StackProtectorLayoutOnly = false;
StringValue FunctionContext;
unsigned MaxCallFrameSize = ~0u; ///< ~0u means: not computed yet.
unsigned CVBytesOfCalleeSavedRegisters = 0;
@@ -759,6 +760,7 @@ struct MachineFrameInfo {
AdjustsStack == Other.AdjustsStack && HasCalls == Other.HasCalls &&
FramePointerPolicy == Other.FramePointerPolicy &&
StackProtector == Other.StackProtector &&
+ StackProtectorLayoutOnly == Other.StackProtectorLayoutOnly &&
FunctionContext == Other.FunctionContext &&
MaxCallFrameSize == Other.MaxCallFrameSize &&
CVBytesOfCalleeSavedRegisters ==
@@ -788,6 +790,8 @@ template <> struct MappingTraits<MachineFrameInfo> {
YamlIO.mapOptional("framePointerPolicy", MFI.FramePointerPolicy);
YamlIO.mapOptional("stackProtector", MFI.StackProtector,
StringValue()); // Don't print it out when it's empty.
+ YamlIO.mapOptional("stackProtectorLayoutOnly", MFI.StackProtectorLayoutOnly,
+ false);
YamlIO.mapOptional("functionContext", MFI.FunctionContext,
StringValue()); // Don't print it out when it's empty.
YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize, (unsigned)~0);
diff --git a/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
index 30699c3c18f1c..67308abe03667 100644
--- a/llvm/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -291,6 +291,10 @@ class MachineFrameInfo {
/// The frame index for the stack protector.
int StackProtectorIdx = -1;
+ /// True if the stack objects should be laid out as if the function had a
+ /// stack protector, even though it does not.
+ bool StackProtectorLayoutOnly = false;
+
/// The frame index for the function context. Used for SjLj exceptions.
int FunctionContextIdx = -1;
@@ -379,6 +383,13 @@ class MachineFrameInfo {
void setStackProtectorIndex(int I) { StackProtectorIdx = I; }
bool hasStackProtectorIndex() const { return StackProtectorIdx != -1; }
+ /// Return true if the stack objects are laid out as if the function had a
+ /// stack protector, even though it does not.
+ bool hasStackProtectorLayoutOnly() const { return StackProtectorLayoutOnly; }
+ void setStackProtectorLayoutOnly(bool B = true) {
+ StackProtectorLayoutOnly = B;
+ }
+
/// Return the index for the function context object.
/// This object is used for SjLj exceptions.
int getFunctionContextIndex() const { return FunctionContextIdx; }
diff --git a/llvm/include/llvm/CodeGen/StackProtector.h b/llvm/include/llvm/CodeGen/StackProtector.h
index 2d6dc76a65fe8..d627ae111322d 100644
--- a/llvm/include/llvm/CodeGen/StackProtector.h
+++ b/llvm/include/llvm/CodeGen/StackProtector.h
@@ -52,6 +52,9 @@ class SSPLayoutInfo {
bool RequireStackProtector = false;
+ // Changes to frame layout are made, but no stack protector is inserted.
+ bool LayoutOnly = false;
+
// A prologue is generated.
bool HasPrologue = false;
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 9cf268ce8ce4f..33b99587ce027 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1561,7 +1561,8 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {
GV.hasFnAttribute(Attribute::StackProtectReq)) {
FPO |= FrameProcedureOptions::StrictSecurityChecks;
}
- } else if (!GV.hasStackProtectorFnAttr()) {
+ } else if (!GV.hasStackProtectorFnAttr() ||
+ GV.hasFnAttribute("stack-protector-layout-only")) {
// __declspec(safebuffers) disables stack guards.
FPO |= FrameProcedureOptions::SafeBuffers;
}
diff --git a/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp b/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp
index a388413525c23..697b9bae707b3 100644
--- a/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp
+++ b/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp
@@ -218,27 +218,30 @@ void LocalStackSlotImpl::calculateFrameObjectOffsets(MachineFunction &Fn) {
Align MaxAlign;
// Make sure that the stack protector comes before the local variables on the
- // stack.
+ // stack. With StackProtectorLayoutOnly these objects are ordered the same
+ // way although no stack protector is inserted.
SmallSet<int, 16> ProtectedObjs;
- if (MFI.hasStackProtectorIndex()) {
+ if (MFI.hasStackProtectorIndex() || MFI.hasStackProtectorLayoutOnly()) {
int StackProtectorFI = MFI.getStackProtectorIndex();
- // We need to make sure we didn't pre-allocate the stack protector when
- // doing this.
- // If we already have a stack protector, this will re-assign it to a slot
- // that is **not** covering the protected objects.
- assert(!MFI.isObjectPreAllocated(StackProtectorFI) &&
- "Stack protector pre-allocated in LocalStackSlotAllocation");
-
StackObjSet LargeArrayObjs;
StackObjSet SmallArrayObjs;
StackObjSet AddrOfObjs;
- // Only place the stack protector in the local stack area if the target
- // allows it.
- if (TFI.isStackIdSafeForLocalArea(MFI.getStackID(StackProtectorFI)))
- AdjustStackOffset(MFI, StackProtectorFI, Offset, StackGrowsDown,
- MaxAlign);
+ if (MFI.hasStackProtectorIndex()) {
+ // We need to make sure we didn't pre-allocate the stack protector when
+ // doing this.
+ // If we already have a stack protector, this will re-assign it to a slot
+ // that is **not** covering the protected objects.
+ assert(!MFI.isObjectPreAllocated(StackProtectorFI) &&
+ "Stack protector pre-allocated in LocalStackSlotAllocation");
+
+ // Only place the stack protector in the local stack area if the target
+ // allows it.
+ if (TFI.isStackIdSafeForLocalArea(MFI.getStackID(StackProtectorFI)))
+ AdjustStackOffset(MFI, StackProtectorFI, Offset, StackGrowsDown,
+ MaxAlign);
+ }
// Assign large stack objects first.
for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 26af6ef073082..1c441f074a666 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -958,6 +958,7 @@ bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS,
MFI.setHasCalls(YamlMFI.HasCalls);
if (YamlMFI.FramePointerPolicy != FramePointerKind::None)
MFI.setFramePointerPolicy(YamlMFI.FramePointerPolicy);
+ MFI.setStackProtectorLayoutOnly(YamlMFI.StackProtectorLayoutOnly);
if (YamlMFI.MaxCallFrameSize != ~0u)
MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);
MFI.setCVBytesOfCalleeSavedRegisters(YamlMFI.CVBytesOfCalleeSavedRegisters);
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index def751e6df6bb..87bf7af1cddf4 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -384,6 +384,7 @@ static void convertMFI(ModuleSlotTrack...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/231651
More information about the cfe-commits
mailing list