nickdesaulniers updated this revision to Diff 297970.
nickdesaulniers added a comment.

- remove modification to docs about legacy fn attr encoding


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87956/new/

https://reviews.llvm.org/D87956

Files:
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/stack-protector.c
  llvm/bindings/go/llvm/ir_test.go
  llvm/bindings/ocaml/llvm/llvm.ml
  llvm/docs/BitCodeFormat.rst
  llvm/docs/LangRef.rst
  llvm/include/llvm/Bitcode/LLVMBitCodes.h
  llvm/include/llvm/IR/Attributes.td
  llvm/lib/AsmParser/LLLexer.cpp
  llvm/lib/AsmParser/LLParser.cpp
  llvm/lib/AsmParser/LLToken.h
  llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
  llvm/lib/CodeGen/StackProtector.cpp
  llvm/lib/IR/Attributes.cpp
  llvm/lib/IR/Verifier.cpp
  llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp
  llvm/lib/Transforms/Utils/CodeExtractor.cpp
  llvm/lib/Transforms/Utils/InlineFunction.cpp
  llvm/test/CodeGen/X86/stack-protector-2.ll
  llvm/test/Transforms/CodeExtractor/PartialInlineAttributes.ll
  llvm/test/Transforms/Inline/inline_nossp.ll
  llvm/test/Transforms/Inline/inline_ssp.ll
  llvm/test/Verifier/function-attribute-nossp-ssp-sspreq-sspstrong.ll
  llvm/utils/emacs/llvm-mode.el
  llvm/utils/kate/llvm.xml
  llvm/utils/llvm.grm
  llvm/utils/vim/syntax/llvm.vim
  llvm/utils/vscode/llvm/syntaxes/ll.tmLanguage.yaml

Index: llvm/utils/vscode/llvm/syntaxes/ll.tmLanguage.yaml
===================================================================
--- llvm/utils/vscode/llvm/syntaxes/ll.tmLanguage.yaml
+++ llvm/utils/vscode/llvm/syntaxes/ll.tmLanguage.yaml
@@ -244,6 +244,7 @@
             \\bspir_func\\b|\
             \\bspir_kernel\\b|\
             \\bsret\\b|\
+            \\bnossp\\b|\
             \\bssp\\b|\
             \\bsspreq\\b|\
             \\bsspstrong\\b|\
Index: llvm/utils/vim/syntax/llvm.vim
===================================================================
--- llvm/utils/vim/syntax/llvm.vim
+++ llvm/utils/vim/syntax/llvm.vim
@@ -147,6 +147,7 @@
       \ spir_func
       \ spir_kernel
       \ sret
+      \ nossp
       \ ssp
       \ sspreq
       \ sspstrong
Index: llvm/utils/llvm.grm
===================================================================
--- llvm/utils/llvm.grm
+++ llvm/utils/llvm.grm
@@ -168,6 +168,7 @@
  | noinline
  | alwaysinline
  | optsize
+ | nossp
  | ssp
  | sspreq
  | returns_twice
Index: llvm/utils/kate/llvm.xml
===================================================================
--- llvm/utils/kate/llvm.xml
+++ llvm/utils/kate/llvm.xml
@@ -92,6 +92,7 @@
       <item> optsize </item>
       <item> readnone </item>
       <item> readonly </item>
+      <item> nossp </item>
       <item> ssp </item>
       <item> sspreq </item>
       <item> sspstrong </item>
Index: llvm/utils/emacs/llvm-mode.el
===================================================================
--- llvm/utils/emacs/llvm-mode.el
+++ llvm/utils/emacs/llvm-mode.el
@@ -26,7 +26,7 @@
          "inaccessiblemem_or_argmemonly" "inlinehint" "jumptable" "minsize" "naked" "nobuiltin"
          "noduplicate" "nofree" "noimplicitfloat" "noinline" "nonlazybind" "noredzone" "noreturn"
          "norecurse" "noundef" "nounwind" "optnone" "optsize" "readnone" "readonly" "returns_twice"
-         "speculatable" "ssp" "sspreq" "sspstrong" "safestack" "sanitize_address" "sanitize_hwaddress" "sanitize_memtag"
+         "speculatable" "nossp" "ssp" "sspreq" "sspstrong" "safestack" "sanitize_address" "sanitize_hwaddress" "sanitize_memtag"
          "sanitize_thread" "sanitize_memory" "strictfp" "uwtable" "willreturn" "writeonly" "immarg") 'symbols) . font-lock-constant-face)
    ;; Variables
    '("%[-a-zA-Z$._][-a-zA-Z$._0-9]*" . font-lock-variable-name-face)
Index: llvm/test/Verifier/function-attribute-nossp-ssp-sspreq-sspstrong.ll
===================================================================
--- /dev/null
+++ llvm/test/Verifier/function-attribute-nossp-ssp-sspreq-sspstrong.ll
@@ -0,0 +1,58 @@
+; RUN: not opt -verify -o - %s 2>&1 | FileCheck %s
+define void @test_1 () #1 { ret void }
+define void @test_2 () #2 { ret void }
+define void @test_3 () #3 { ret void }
+define void @test_4 () #4 { ret void }
+define void @test_5 () #5 { ret void }
+define void @test_6 () #6 { ret void }
+define void @test_7 () #7 { ret void }
+define void @test_8 () #8 { ret void }
+define void @test_9 () #9 { ret void }
+define void @test_10 () #10 { ret void }
+define void @test_11 () #10 { ret void }
+define void @test_12 () #10 { ret void }
+define void @test_13 () #10 { ret void }
+define void @test_14 () #10 { ret void }
+
+attributes #0 = { nossp }
+attributes #1 = { ssp }
+attributes #2 = { sspreq }
+attributes #3 = { sspstrong }
+
+attributes #4 = { nossp ssp }
+attributes #5 = { nossp sspreq }
+attributes #6 = { nossp sspstrong }
+
+attributes #7 = { ssp sspreq }
+attributes #8 = { ssp sspstrong }
+
+attributes #9 = { sspreq sspstrong }
+
+attributes #10 = { nossp ssp sspreq }
+attributes #11 = { nossp ssp sspstrong }
+attributes #12 = { nossp sspreq sspstrong }
+attributes #13 = { ssp sspreq sspstrong }
+attributes #14 = { nossp ssp sspreq sspstrong }
+
+; CHECK: fn attrs should be mutually exclusive
+; CHECK-NEXT: void ()* @test_4
+; CHECK: fn attrs should be mutually exclusive
+; CHECK-NEXT: void ()* @test_5
+; CHECK: fn attrs should be mutually exclusive
+; CHECK-NEXT: void ()* @test_6
+; CHECK: fn attrs should be mutually exclusive
+; CHECK-NEXT: void ()* @test_7
+; CHECK: fn attrs should be mutually exclusive
+; CHECK-NEXT: void ()* @test_8
+; CHECK: fn attrs should be mutually exclusive
+; CHECK-NEXT: void ()* @test_9
+; CHECK: fn attrs should be mutually exclusive
+; CHECK-NEXT: void ()* @test_10
+; CHECK: fn attrs should be mutually exclusive
+; CHECK-NEXT: void ()* @test_11
+; CHECK: fn attrs should be mutually exclusive
+; CHECK-NEXT: void ()* @test_12
+; CHECK: fn attrs should be mutually exclusive
+; CHECK-NEXT: void ()* @test_13
+; CHECK: fn attrs should be mutually exclusive
+; CHECK-NEXT: void ()* @test_14
Index: llvm/test/Transforms/Inline/inline_ssp.ll
===================================================================
--- llvm/test/Transforms/Inline/inline_ssp.ll
+++ llvm/test/Transforms/Inline/inline_ssp.ll
@@ -1,6 +1,10 @@
 ; RUN: opt -inline %s -S | FileCheck %s
 ; RUN: opt -passes='cgscc(inline)' %s -S | FileCheck %s
 ; Ensure SSP attributes are propagated correctly when inlining.
+; This test case covers callers that are unspecified in their level of stack
+; protection. See also llvm/test/Transforms/Inline/inline_nossp.ll
+; which tests callers with ``nossp`` function attribute which is stack
+; protection explicitly disabled.
 
 @.str = private unnamed_addr constant [11 x i8] c"fun_nossp\0A\00", align 1
 @.str1 = private unnamed_addr constant [9 x i8] c"fun_ssp\0A\00", align 1
Index: llvm/test/Transforms/Inline/inline_nossp.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/Inline/inline_nossp.ll
@@ -0,0 +1,38 @@
+; RUN: opt -inline -o - -S %s | FileCheck %s
+; RUN: opt -passes='cgscc(inline)' %s -S | FileCheck %s
+; RUN: opt -always-inline -o - -S %s | FileCheck %s
+
+declare dso_local void @foo(i8*)
+
+define dso_local void @bar(i64 %0) #0 {
+  %2 = alloca i64, align 8
+  store i64 %0, i64* %2, align 8
+  %3 = load i64, i64* %2, align 8
+  %4 = alloca i8, i64 %3, align 16
+  call void @foo(i8* %4)
+  ret void
+}
+
+define dso_local void @baz(i64 %0) #1 {
+  %2 = alloca i64, align 8
+  store i64 %0, i64* %2, align 8
+  %3 = load i64, i64* %2, align 8
+  %4 = alloca i8, i64 %3, align 16
+  call void @foo(i8* %4)
+  ret void
+}
+
+define dso_local void @quux() #2 {
+; Check that the calls to @bar and @baz are not inlined into @quux, since @quux
+; does not want a stack protector.
+; CHECK-LABEL: @quux
+; CHECK-NEXT: call void @bar
+; CHECK-NEXT: call void @baz
+  call void @bar(i64 1024)
+  call void @baz(i64 1024)
+  ret void
+}
+
+attributes #0 = { sspstrong }
+attributes #1 = { sspstrong alwaysinline }
+attributes #2 = { nossp }
Index: llvm/test/Transforms/CodeExtractor/PartialInlineAttributes.ll
===================================================================
--- llvm/test/Transforms/CodeExtractor/PartialInlineAttributes.ll
+++ llvm/test/Transforms/CodeExtractor/PartialInlineAttributes.ll
@@ -73,10 +73,10 @@
 attributes #0 = {
   inlinehint minsize noduplicate noimplicitfloat norecurse noredzone nounwind
   nonlazybind optsize safestack sanitize_address sanitize_hwaddress sanitize_memory
-  sanitize_thread ssp sspreq sspstrong strictfp uwtable "foo"="bar"
+  sanitize_thread sspstrong strictfp uwtable "foo"="bar"
   "patchable-function"="prologue-short-redirect" "probe-stack"="_foo_guard" "stack-probe-size"="4096" }
 
-; CHECK: attributes [[FN_ATTRS]] = { inlinehint minsize noduplicate noimplicitfloat norecurse noredzone nounwind nonlazybind optsize safestack sanitize_address sanitize_hwaddress sanitize_memory sanitize_thread ssp sspreq sspstrong strictfp uwtable "foo"="bar" "patchable-function"="prologue-short-redirect" "probe-stack"="_foo_guard" "stack-probe-size"="4096" }
+; CHECK: attributes [[FN_ATTRS]] = { inlinehint minsize noduplicate noimplicitfloat norecurse noredzone nounwind nonlazybind optsize safestack sanitize_address sanitize_hwaddress sanitize_memory sanitize_thread sspstrong strictfp uwtable "foo"="bar" "patchable-function"="prologue-short-redirect" "probe-stack"="_foo_guard" "stack-probe-size"="4096" }
 
 ; attributes to drop
 attributes #1 = {
Index: llvm/test/CodeGen/X86/stack-protector-2.ll
===================================================================
--- llvm/test/CodeGen/X86/stack-protector-2.ll
+++ llvm/test/CodeGen/X86/stack-protector-2.ll
@@ -1,5 +1,5 @@
 ; RUN: llc -mtriple=x86_64-pc-linux-gnu -start-before=stack-protector -stop-after=stack-protector -o - < %s | FileCheck %s
-; Bugs 42238/43308: Test some additional situations not caught previously.
+; Bugs 42238/43308/47479: Test some additional situations not caught previously.
 
 define void @store_captures() #0 {
 ; CHECK-LABEL: @store_captures(
@@ -162,4 +162,31 @@
 
 declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg)
 
+
+; Test that the same function does not get a canary if nossp fn attr is set.
+declare dso_local void @foo(i8*)
+
+define dso_local void @bar_sspstrong(i64 %0) #0 {
+; CHECK-LABEL: @bar_sspstrong
+; CHECK-NEXT: %StackGuardSlot = alloca i8*
+  %2 = alloca i64, align 8
+  store i64 %0, i64* %2, align 8
+  %3 = load i64, i64* %2, align 8
+  %4 = alloca i8, i64 %3, align 16
+  call void @foo(i8* %4)
+  ret void
+}
+
+define dso_local void @bar_nossp(i64 %0) #1 {
+; CHECK-LABEL: @bar_nossp
+; CHECK-NEXT: %2 = alloca i64
+  %2 = alloca i64, align 8
+  store i64 %0, i64* %2, align 8
+  %3 = load i64, i64* %2, align 8
+  %4 = alloca i8, i64 %3, align 16
+  call void @foo(i8* %4)
+  ret void
+}
+
 attributes #0 = { sspstrong }
+attributes #1 = { nossp }
Index: llvm/lib/Transforms/Utils/InlineFunction.cpp
===================================================================
--- llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1676,6 +1676,16 @@
       return InlineResult::failure("incompatible GC");
   }
 
+  // Inlining a function that explicitly should not have a stack protector may
+  // break the code if inlined into a function that does have a stack
+  // protector.
+  if (Caller->hasFnAttribute(Attribute::NoStackProtect))
+    if (CalledFunc->hasFnAttribute(Attribute::StackProtect) ||
+        CalledFunc->hasFnAttribute(Attribute::StackProtectStrong) ||
+        CalledFunc->hasFnAttribute(Attribute::StackProtectReq))
+      return InlineResult::failure(
+          "non-stack-protected caller would inline stack-protected callee");
+
   // Get the personality function from the callee if it contains a landing pad.
   Constant *CalledPersonality =
       CalledFunc->hasPersonalityFn()
Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp
===================================================================
--- llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -925,6 +925,7 @@
       case Attribute::SanitizeHWAddress:
       case Attribute::SanitizeMemTag:
       case Attribute::SpeculativeLoadHardening:
+      case Attribute::NoStackProtect:
       case Attribute::StackProtect:
       case Attribute::StackProtectReq:
       case Attribute::StackProtectStrong:
Index: llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp
===================================================================
--- llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp
+++ llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp
@@ -68,6 +68,7 @@
       .Case("sanitize_thread", Attribute::SanitizeThread)
       .Case("sanitize_memtag", Attribute::SanitizeMemTag)
       .Case("speculative_load_hardening", Attribute::SpeculativeLoadHardening)
+      .Case("nossp", Attribute::NoStackProtect)
       .Case("ssp", Attribute::StackProtect)
       .Case("sspreq", Attribute::StackProtectReq)
       .Case("sspstrong", Attribute::StackProtectStrong)
Index: llvm/lib/IR/Verifier.cpp
===================================================================
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -1577,6 +1577,7 @@
   case Attribute::NoInline:
   case Attribute::AlwaysInline:
   case Attribute::OptimizeForSize:
+  case Attribute::NoStackProtect:
   case Attribute::StackProtect:
   case Attribute::StackProtectReq:
   case Attribute::StackProtectStrong:
@@ -1971,6 +1972,21 @@
       CheckFailed(
           "\"patchable-function-entry\" takes an unsigned integer: " + S, V);
   }
+  {
+    unsigned N = 0;
+    if (Attrs.hasFnAttribute(Attribute::NoStackProtect))
+      ++N;
+    if (Attrs.hasFnAttribute(Attribute::StackProtect))
+      ++N;
+    if (Attrs.hasFnAttribute(Attribute::StackProtectReq))
+      ++N;
+    if (Attrs.hasFnAttribute(Attribute::StackProtectStrong))
+      ++N;
+    Assert(N < 2,
+           "nossp, ssp, sspreq, sspstrong fn attrs should be mutually "
+           "exclusive",
+           V);
+  }
 }
 
 void Verifier::verifyFunctionMetadata(
Index: llvm/lib/IR/Attributes.cpp
===================================================================
--- llvm/lib/IR/Attributes.cpp
+++ llvm/lib/IR/Attributes.cpp
@@ -421,6 +421,8 @@
     return "speculative_load_hardening";
   if (hasAttribute(Attribute::Speculatable))
     return "speculatable";
+  if (hasAttribute(Attribute::NoStackProtect))
+    return "nossp";
   if (hasAttribute(Attribute::StackProtect))
     return "ssp";
   if (hasAttribute(Attribute::StackProtectReq))
@@ -1899,9 +1901,11 @@
 /// If the inlined function had a higher stack protection level than the
 /// calling function, then bump up the caller's stack protection level.
 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
+  // Caller should never inherit a stack protector function attribute if the
+  // caller was explicitly annotated as nossp.
+  if (Caller.hasFnAttribute(Attribute::NoStackProtect))
+    return;
   // If upgrading the SSP attribute, clear out the old SSP Attributes first.
-  // Having multiple SSP attributes doesn't actually hurt, but it adds useless
-  // clutter to the IR.
   AttrBuilder OldSSPAttr;
   OldSSPAttr.addAttribute(Attribute::StackProtect)
       .addAttribute(Attribute::StackProtectStrong)
Index: llvm/lib/CodeGen/StackProtector.cpp
===================================================================
--- llvm/lib/CodeGen/StackProtector.cpp
+++ llvm/lib/CodeGen/StackProtector.cpp
@@ -270,13 +270,15 @@
 /// regardless of size, functions with any buffer regardless of type and size,
 /// functions with aggregates that contain any buffer regardless of type and
 /// size, and functions that contain stack-based variables that have had their
-/// address taken.
+/// address taken. The heuristic will be disregarded for functions explicitly
+/// marked nossp.
 bool StackProtector::RequiresStackProtector() {
   bool Strong = false;
   bool NeedsProtector = false;
   HasPrologue = findStackProtectorIntrinsic(*F);
 
-  if (F->hasFnAttribute(Attribute::SafeStack))
+  if (F->hasFnAttribute(Attribute::SafeStack) ||
+      F->hasFnAttribute(Attribute::NoStackProtect))
     return false;
 
   // We are constructing the OptimizationRemarkEmitter on the fly rather than
Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
===================================================================
--- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -697,6 +697,8 @@
     return bitc::ATTR_KIND_SPECULATABLE;
   case Attribute::StackAlignment:
     return bitc::ATTR_KIND_STACK_ALIGNMENT;
+  case Attribute::NoStackProtect:
+    return bitc::ATTR_KIND_NO_STACK_PROTECT;
   case Attribute::StackProtect:
     return bitc::ATTR_KIND_STACK_PROTECT;
   case Attribute::StackProtectReq:
Index: llvm/lib/AsmParser/LLToken.h
===================================================================
--- llvm/lib/AsmParser/LLToken.h
+++ llvm/lib/AsmParser/LLToken.h
@@ -223,6 +223,7 @@
   kw_returns_twice,
   kw_signext,
   kw_speculatable,
+  kw_nossp,
   kw_ssp,
   kw_sspreq,
   kw_sspstrong,
Index: llvm/lib/AsmParser/LLParser.cpp
===================================================================
--- llvm/lib/AsmParser/LLParser.cpp
+++ llvm/lib/AsmParser/LLParser.cpp
@@ -1335,6 +1335,9 @@
     case lltok::kw_returns_twice:
       B.addAttribute(Attribute::ReturnsTwice); break;
     case lltok::kw_speculatable: B.addAttribute(Attribute::Speculatable); break;
+    case lltok::kw_nossp:
+      B.addAttribute(Attribute::NoStackProtect);
+      break;
     case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break;
     case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break;
     case lltok::kw_sspstrong:
@@ -1739,6 +1742,7 @@
     case lltok::kw_sanitize_memory:
     case lltok::kw_sanitize_thread:
     case lltok::kw_speculative_load_hardening:
+    case lltok::kw_nossp:
     case lltok::kw_ssp:
     case lltok::kw_sspreq:
     case lltok::kw_sspstrong:
@@ -1843,6 +1847,7 @@
     case lltok::kw_sanitize_memory:
     case lltok::kw_sanitize_thread:
     case lltok::kw_speculative_load_hardening:
+    case lltok::kw_nossp:
     case lltok::kw_ssp:
     case lltok::kw_sspreq:
     case lltok::kw_sspstrong:
Index: llvm/lib/AsmParser/LLLexer.cpp
===================================================================
--- llvm/lib/AsmParser/LLLexer.cpp
+++ llvm/lib/AsmParser/LLLexer.cpp
@@ -678,6 +678,7 @@
   KEYWORD(signext);
   KEYWORD(speculatable);
   KEYWORD(sret);
+  KEYWORD(nossp);
   KEYWORD(ssp);
   KEYWORD(sspreq);
   KEYWORD(sspstrong);
Index: llvm/include/llvm/IR/Attributes.td
===================================================================
--- llvm/include/llvm/IR/Attributes.td
+++ llvm/include/llvm/IR/Attributes.td
@@ -179,6 +179,9 @@
 /// Function can be speculated.
 def Speculatable : EnumAttr<"speculatable">;
 
+/// Stack protection explicitly disabled.
+def NoStackProtect : EnumAttr<"nossp">;
+
 /// Stack protection.
 def StackProtect : EnumAttr<"ssp">;
 
Index: llvm/include/llvm/Bitcode/LLVMBitCodes.h
===================================================================
--- llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -650,6 +650,7 @@
   ATTR_KIND_NULL_POINTER_IS_VALID = 67,
   ATTR_KIND_NOUNDEF = 68,
   ATTR_KIND_BYREF = 69,
+  ATTR_KIND_NO_STACK_PROTECT = 70,
 };
 
 enum ComdatSelectionKindCodes {
Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -1820,6 +1820,21 @@
     undefined behavior, the undefined behavior may be observed even
     if the call site is dead code.
 
+``nossp``
+    This attribute indicates the function should not emit a stack smashing
+    protector. This is useful for code that intentionally manipulates the stack
+    canary, such as operating system kernel code that must save/restore such
+    canary values on context switch.
+
+    If a function with the ``nossp`` attribute calls a callee function that has
+    a stack protector function attribute, such as ``ssp``, ``sspreq``, or
+    ``sspstrong``, then the callee will not be inline substituted into the
+    caller. Even when the callee is ``alwaysinline``, the above holds.
+
+    Such inlining might break assumptions in the caller that it was
+    built without stack protection. This permits the callee to retain its stack
+    protector.
+
 ``ssp``
     This attribute indicates that the function should emit a stack
     smashing protector. It is in the form of a "canary" --- a random value
Index: llvm/docs/BitCodeFormat.rst
===================================================================
--- llvm/docs/BitCodeFormat.rst
+++ llvm/docs/BitCodeFormat.rst
@@ -1068,6 +1068,8 @@
 * code 66: ``no_merge``
 * code 67: ``null_pointer_is_valid``
 * code 68: ``noundef``
+* code 69: ``byref``
+* code 70: ``nossp``
 
 .. note::
   The ``allocsize`` attribute has a special encoding for its arguments. Its two
Index: llvm/bindings/ocaml/llvm/llvm.ml
===================================================================
--- llvm/bindings/ocaml/llvm/llvm.ml
+++ llvm/bindings/ocaml/llvm/llvm.ml
@@ -122,6 +122,7 @@
   | Noinline
   | Alwaysinline
   | Optsize
+  | Nossp
   | Ssp
   | Sspreq
   | Alignment of int
Index: llvm/bindings/go/llvm/ir_test.go
===================================================================
--- llvm/bindings/go/llvm/ir_test.go
+++ llvm/bindings/go/llvm/ir_test.go
@@ -78,6 +78,7 @@
 		"returns_twice",
 		"signext",
 		"safestack",
+		"nossp",
 		"ssp",
 		"sspreq",
 		"sspstrong",
Index: clang/test/CodeGen/stack-protector.c
===================================================================
--- clang/test/CodeGen/stack-protector.c
+++ clang/test/CodeGen/stack-protector.c
@@ -36,7 +36,7 @@
 // SSPREQ: attributes #[[A]] = {{.*}} sspreq
 
 // SAFESTACK-NOSSP: attributes #[[A]] = {{.*}} safestack
-// SAFESTACK-NOSSP-NOT: ssp
+// SAFESTACK-NOSSP-NOT: attributes #[[A]] = {{.*}} ssp
 
 // SAFESTACK-SSP: attributes #[[A]] = {{.*}} safestack ssp{{ }}
 // SAFESTACK-SSPSTRONG: attributes #[[A]] = {{.*}} safestack sspstrong
@@ -47,6 +47,11 @@
 // SSPSTRONG-NOT: attributes #[[B]] = {{.*}} sspstrong
 // SSPREQ-NOT: attributes #[[B]] = {{.*}} sspreq
 
+// NOSSP: attributes #[[B]] = {{.*}} nossp
+// SSP: attributes #[[B]] = {{.*}} nossp
+// SSPSTRONG: attributes #[[B]] = {{.*}} nossp
+// SSPREQ: attributes #[[B]] = {{.*}} nossp
+
 // SAFESTACK-SSP: attributes #[[B]] = {{.*}} safestack
 // SAFESTACK-SSP-NOT: attributes #[[B]] = {{.*}} safestack ssp{{ }}
 // SAFESTACK-SSPSTRONG: attributes #[[B]] = {{.*}} safestack
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -1594,14 +1594,14 @@
   if (!hasUnwindExceptions(LangOpts))
     B.addAttribute(llvm::Attribute::NoUnwind);
 
-  if (!D || !D->hasAttr<NoStackProtectorAttr>()) {
-    if (LangOpts.getStackProtector() == LangOptions::SSPOn)
-      B.addAttribute(llvm::Attribute::StackProtect);
-    else if (LangOpts.getStackProtector() == LangOptions::SSPStrong)
-      B.addAttribute(llvm::Attribute::StackProtectStrong);
-    else if (LangOpts.getStackProtector() == LangOptions::SSPReq)
-      B.addAttribute(llvm::Attribute::StackProtectReq);
-  }
+  if (D && D->hasAttr<NoStackProtectorAttr>())
+    B.addAttribute(llvm::Attribute::NoStackProtect);
+  else if (LangOpts.getStackProtector() == LangOptions::SSPOn)
+    B.addAttribute(llvm::Attribute::StackProtect);
+  else if (LangOpts.getStackProtector() == LangOptions::SSPStrong)
+    B.addAttribute(llvm::Attribute::StackProtectStrong);
+  else if (LangOpts.getStackProtector() == LangOptions::SSPReq)
+    B.addAttribute(llvm::Attribute::StackProtectReq);
 
   if (!D) {
     // If we don't have a declaration to control inlining, the function isn't
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -3872,6 +3872,10 @@
 
     int bar(int y); // bar can be built with the stack protector.
 
+A callee that has a stack protector will not be inlined into a
+``__attribute__((no_stack_protector))`` caller, even if the callee is marked
+``__attribute__((always_inline))``.
+
     }];
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to