Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -2170,3 +2170,9 @@ let Subjects = SubjectList<[Var, Function, CXXRecord]>; let Documentation = [InternalLinkageDocs]; } + +def GcLeafFunction : InheritableAttr { + let Spellings = [GNU<"gc_leaf_function">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [Undocumented]; +} Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1488,6 +1488,8 @@ RetAttrs.addAttribute(llvm::Attribute::NoAlias); if (TargetDecl->hasAttr()) RetAttrs.addAttribute(llvm::Attribute::NonNull); + if (TargetDecl->hasAttr()) + FuncAttrs.addAttribute("gc-leaf-function"); HasOptnone = TargetDecl->hasAttr(); } Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5318,6 +5318,9 @@ case AttributeList::AT_InternalLinkage: handleInternalLinkageAttr(S, D, Attr); break; + case AttributeList::AT_GcLeafFunction: + handleSimpleAttribute(S, D, Attr); + break; // Microsoft attributes: case AttributeList::AT_MSNoVTable: Index: test/CodeGen/attr-gc-leaf-function.c =================================================================== --- /dev/null +++ test/CodeGen/attr-gc-leaf-function.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +void foo(void) __attribute__((gc_leaf_function)); + +void test(void) { + // CHECK: call void @foo() [[ATTRS_CALL:#[0-9]+]] + foo(); +} + +// CHECK: declare void @foo() [[ATTRS_DECL:#[0-9]+]] +// CHECK: attributes [[ATTRS_DECL]] = { {{.*}}"gc-leaf-function"{{.*}} } +// CHECK: attributes [[ATTRS_CALL]] = { {{.*}}"gc-leaf-function"{{.*}} }