mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-19 05:46:45 +00:00
Implement the no_split_stack attribute.
This is a GNU attribute that allows split stacks to be turned off on a per-function basis. Differential Revision: http://reviews.llvm.org/D3817 llvm-svn: 209167
This commit is contained in:
parent
973141a035
commit
b4728c12e8
@ -823,6 +823,12 @@ def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips> {
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
def NoSplitStack : InheritableAttr {
|
||||
let Spellings = [GCC<"no_split_stack">];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
let Documentation = [NoSplitStackDocs];
|
||||
}
|
||||
|
||||
def NonNull : InheritableAttr {
|
||||
let Spellings = [GCC<"nonnull">];
|
||||
let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag,
|
||||
|
@ -371,6 +371,15 @@ of the condition.
|
||||
}];
|
||||
}
|
||||
|
||||
def NoSplitStackDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
The ``no_split_stack`` attribute disables the emission of the split stack
|
||||
preamble for a particular function. It has no effect if ``-fsplit-stack``
|
||||
is not specified.
|
||||
}];
|
||||
}
|
||||
|
||||
def ObjCRequiresSuperDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
|
@ -1117,7 +1117,8 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
|
||||
FuncAttrs.addAttribute(llvm::Attribute::NoRedZone);
|
||||
if (CodeGenOpts.NoImplicitFloat)
|
||||
FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat);
|
||||
if (CodeGenOpts.EnableSegmentedStacks)
|
||||
if (CodeGenOpts.EnableSegmentedStacks &&
|
||||
!(TargetDecl && TargetDecl->hasAttr<NoSplitStackAttr>()))
|
||||
FuncAttrs.addAttribute("split-stack");
|
||||
|
||||
if (AttrOnCallSite) {
|
||||
|
@ -4180,6 +4180,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
||||
case AttributeList::AT_NoCommon:
|
||||
handleSimpleAttribute<NoCommonAttr>(S, D, Attr);
|
||||
break;
|
||||
case AttributeList::AT_NoSplitStack:
|
||||
handleSimpleAttribute<NoSplitStackAttr>(S, D, Attr);
|
||||
break;
|
||||
case AttributeList::AT_NonNull:
|
||||
if (ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(D))
|
||||
handleNonNullAttrParameter(S, PVD, Attr);
|
||||
|
@ -5,13 +5,21 @@ int foo() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((no_split_stack))
|
||||
int nosplit() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
return foo();
|
||||
}
|
||||
|
||||
// CHECK-SEGSTK: define i32 @foo() #0 {
|
||||
// CHECK-SEGSTK: define i32 @main() #0 {
|
||||
// CHECK-SEGSTK: #0 = { {{.*}} "split-stack" {{.*}} }
|
||||
// CHECK-SEGSTK: define i32 @foo() [[SS:#[0-9]+]] {
|
||||
// CHECK-SEGSTK: define i32 @nosplit() [[NSS:#[0-9]+]] {
|
||||
// CHECK-SEGSTK: define i32 @main() [[SS]] {
|
||||
// CHECK-SEGSTK-NOT: [[NSS]] = { {{.*}} "split-stack" {{.*}} }
|
||||
// CHECK-SEGSTK: [[SS]] = { {{.*}} "split-stack" {{.*}} }
|
||||
// CHECK-SEGSTK-NOT: [[NSS]] = { {{.*}} "split-stack" {{.*}} }
|
||||
|
||||
// CHECK-NOSEGSTK: define i32 @foo() #0 {
|
||||
// CHECK-NOSEGSTK: define i32 @main() #0 {
|
||||
|
33
clang/test/CodeGenCXX/split-stacks.cpp
Normal file
33
clang/test/CodeGenCXX/split-stacks.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsplit-stack -S -std=c++11 %s -emit-llvm -o - | FileCheck -check-prefix=CHECK-SEGSTK %s
|
||||
// RUN: %clang -target x86_64-linux-gnu -S -std=c++11 %s -emit-llvm -o - | FileCheck -check-prefix=CHECK-NOSEGSTK %s
|
||||
|
||||
int foo() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[gnu::no_split_stack]]
|
||||
int tnosplit() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
[[gnu::no_split_stack]]
|
||||
int nosplit() {
|
||||
return tnosplit<int>();
|
||||
}
|
||||
|
||||
// CHECK-SEGSTK: define i32 @_Z3foov() [[SS:#[0-9]+]] {
|
||||
// CHECK-SEGSTK: define i32 @_Z7nosplitv() [[NSS1:#[0-9]+]] {
|
||||
// CHECK-SEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] {
|
||||
// CHECK-SEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
|
||||
// CHECK-SEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
|
||||
// CHECK-SEGSTK: [[SS]] = { {{.*}} "split-stack" {{.*}} }
|
||||
// CHECK-SEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
|
||||
// CHECK-SEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
|
||||
|
||||
// CHECK-NOSEGSTK: define i32 @_Z3foov() [[NSS0:#[0-9]+]] {
|
||||
// CHECK-NOSEGSTK: define i32 @_Z7nosplitv() [[NSS1:#[0-9]+]] {
|
||||
// CHECK-NOSEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] {
|
||||
// CHECK-NOSEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
|
||||
// CHECK-NOSEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
|
||||
// CHECK-NOSEGSTK-NOT: [[NSS3]] = { {{.*}} "split-stack" {{.*}} }
|
34
clang/test/SemaCXX/attr-no-split-stack.cpp
Normal file
34
clang/test/SemaCXX/attr-no-split-stack.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
|
||||
|
||||
int i __attribute__((no_split_stack)); // expected-error {{'no_split_stack' attribute only applies to functions}}
|
||||
|
||||
void f1() __attribute__((no_split_stack));
|
||||
void f2() __attribute__((no_split_stack(1))); // expected-error {{'no_split_stack' attribute takes no arguments}}
|
||||
|
||||
template <typename T>
|
||||
void tf1() __attribute__((no_split_stack));
|
||||
|
||||
int f3(int __attribute__((no_split_stack)), int); // expected-error{{'no_split_stack' attribute only applies to functions}}
|
||||
|
||||
struct A {
|
||||
int f __attribute__((no_split_stack)); // expected-error{{'no_split_stack' attribute only applies to functions}}
|
||||
void mf1() __attribute__((no_split_stack));
|
||||
static void mf2() __attribute__((no_split_stack));
|
||||
};
|
||||
|
||||
int ci [[gnu::no_split_stack]]; // expected-error {{'no_split_stack' attribute only applies to functions}}
|
||||
|
||||
[[gnu::no_split_stack]] void cf1();
|
||||
[[gnu::no_split_stack(1)]] void cf2(); // expected-error {{'no_split_stack' attribute takes no arguments}}
|
||||
|
||||
template <typename T>
|
||||
[[gnu::no_split_stack]]
|
||||
void ctf1();
|
||||
|
||||
int cf3(int c[[gnu::no_split_stack]], int); // expected-error{{'no_split_stack' attribute only applies to functions}}
|
||||
|
||||
struct CA {
|
||||
int f [[gnu::no_split_stack]]; // expected-error{{'no_split_stack' attribute only applies to functions}}
|
||||
[[gnu::no_split_stack]] void mf1();
|
||||
[[gnu::no_split_stack]] static void mf2();
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user