summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/Attr.td6
-rw-r--r--clang/include/clang/Basic/AttrDocs.td24
-rw-r--r--clang/lib/CodeGen/CGCall.cpp4
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp3
-rw-r--r--clang/test/CodeGen/attr-speculative-load-hardening.cpp18
-rw-r--r--clang/test/CodeGen/attr-speculative-load-hardening.m9
-rw-r--r--clang/test/Misc/pragma-attribute-supported-attributes-list.test3
-rw-r--r--clang/test/SemaCXX/attr-speculative-load-hardening.cpp34
-rw-r--r--llvm/docs/LangRef.rst22
9 files changed, 109 insertions, 14 deletions
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index a6be48c234f..5b52ba4f64b 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3091,3 +3091,9 @@ def AlwaysDestroy : InheritableAttr {
let Subjects = SubjectList<[Var]>;
let Documentation = [AlwaysDestroyDocs];
}
+
+def SpeculativeLoadHardening : InheritableAttr {
+ let Spellings = [Clang<"speculative_load_hardening">];
+ let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
+ let Documentation = [SpeculativeLoadHardeningDocs];
+}
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index e38c557f140..203ae827195 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -3629,3 +3629,27 @@ GNU inline semantics are the default behavior with ``-std=gnu89``,
``-std=c89``, ``-std=c94``, or ``-fgnu89-inline``.
}];
}
+
+def SpeculativeLoadHardeningDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+ This attribute can be applied to a function declaration in order to indicate
+ that `Speculative Load Hardening <https://llvm.org/docs/SpeculativeLoadHardening.html>`_
+ should be enabled for the function body. This can also be applied to a method
+ in Objective C.
+
+ Speculative Load Hardening is a best-effort mitigation against
+ information leak attacks that make use of control flow
+ miss-speculation - specifically miss-speculation of whether a branch
+ is taken or not. Typically vulnerabilities enabling such attacks are
+ classified as "Spectre variant #1". Notably, this does not attempt to
+ mitigate against miss-speculation of branch target, classified as
+ "Spectre variant #2" vulnerabilities.
+
+ When inlining, the attribute is sticky. Inlining a function that
+ carries this attribute will cause the caller to gain the
+ attribute. This is intended to provide a maximally conservative model
+ where the code in a function annotated with this attribute will always
+ (even after inlining) end up hardened.
+ }];
+}
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 0ec5c7fb452..6d89f3919fd 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1791,6 +1791,8 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
if (CodeGenOpts.Backchain)
FuncAttrs.addAttribute("backchain");
+ // FIXME: The interaction of this attribute with the SLH command line flag
+ // has not been determined.
if (CodeGenOpts.SpeculativeLoadHardening)
FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
}
@@ -1854,6 +1856,8 @@ void CodeGenModule::ConstructAttributeList(
FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
if (TargetDecl->hasAttr<ConvergentAttr>())
FuncAttrs.addAttribute(llvm::Attribute::Convergent);
+ if (TargetDecl->hasAttr<SpeculativeLoadHardeningAttr>())
+ FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
AddAttributesFromFunctionProtoType(
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 9f5325d109e..be662b9b914 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6373,6 +6373,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_Section:
handleSectionAttr(S, D, AL);
break;
+ case ParsedAttr::AT_SpeculativeLoadHardening:
+ handleSimpleAttribute<SpeculativeLoadHardeningAttr>(S, D, AL);
+ break;
case ParsedAttr::AT_CodeSeg:
handleCodeSegAttr(S, D, AL);
break;
diff --git a/clang/test/CodeGen/attr-speculative-load-hardening.cpp b/clang/test/CodeGen/attr-speculative-load-hardening.cpp
new file mode 100644
index 00000000000..e2eb805cbb8
--- /dev/null
+++ b/clang/test/CodeGen/attr-speculative-load-hardening.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1
+// RUN: %clang_cc1 -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK2
+//
+// Check that we set the attribute on each function.
+
+[[clang::speculative_load_hardening]]
+int test1() {
+ return 42;
+}
+
+int __attribute__((speculative_load_hardening)) test2() {
+ return 42;
+}
+// CHECK1: @{{.*}}test1{{.*}}[[SLH1:#[0-9]+]]
+// CHECK1: attributes [[SLH1]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK2: @{{.*}}test2{{.*}}[[SLH2:#[0-9]+]]
+// CHECK2: attributes [[SLH2]] = { {{.*}}speculative_load_hardening{{.*}} }
diff --git a/clang/test/CodeGen/attr-speculative-load-hardening.m b/clang/test/CodeGen/attr-speculative-load-hardening.m
new file mode 100644
index 00000000000..2de945b974f
--- /dev/null
+++ b/clang/test/CodeGen/attr-speculative-load-hardening.m
@@ -0,0 +1,9 @@
+// RUN: %clang -emit-llvm %s -o - -S | FileCheck %s -check-prefix=SLH
+
+int main() __attribute__((speculative_load_hardening)) {
+ return 0;
+}
+
+// SLH: @{{.*}}main{{.*}}[[SLH:#[0-9]+]]
+
+// SLH: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 0a54c6c05ad..0aa923de7df 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -2,7 +2,7 @@
// The number of supported attributes should never go down!
-// CHECK: #pragma clang attribute supports 129 attributes:
+// CHECK: #pragma clang attribute supports 130 attributes:
// CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function)
// CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function)
// CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function)
@@ -116,6 +116,7 @@
// CHECK-NEXT: ScopedLockable (SubjectMatchRule_record)
// CHECK-NEXT: Section (SubjectMatchRule_function, SubjectMatchRule_variable_is_global, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property)
// CHECK-NEXT: SetTypestate (SubjectMatchRule_function_is_member)
+// CHECK-NEXT: SpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: SwiftContext (SubjectMatchRule_variable_is_parameter)
// CHECK-NEXT: SwiftErrorResult (SubjectMatchRule_variable_is_parameter)
// CHECK-NEXT: SwiftIndirectResult (SubjectMatchRule_variable_is_parameter)
diff --git a/clang/test/SemaCXX/attr-speculative-load-hardening.cpp b/clang/test/SemaCXX/attr-speculative-load-hardening.cpp
new file mode 100644
index 00000000000..bba3b6921e8
--- /dev/null
+++ b/clang/test/SemaCXX/attr-speculative-load-hardening.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+int i __attribute__((speculative_load_hardening)); // expected-error {{'speculative_load_hardening' attribute only applies to functions}}
+
+void f1() __attribute__((speculative_load_hardening));
+void f2() __attribute__((speculative_load_hardening(1))); // expected-error {{'speculative_load_hardening' attribute takes no arguments}}
+
+template <typename T>
+void tf1() __attribute__((speculative_load_hardening));
+
+int f3(int __attribute__((speculative_load_hardening)), int); // expected-error {{'speculative_load_hardening' attribute only applies to functions}}
+
+struct A {
+ int f __attribute__((speculative_load_hardening)); // expected-error {{'speculative_load_hardening' attribute only applies to functions}}
+ void mf1() __attribute__((speculative_load_hardening));
+ static void mf2() __attribute__((speculative_load_hardening));
+};
+
+int ci [[clang::speculative_load_hardening]]; // expected-error {{'speculative_load_hardening' attribute only applies to functions}}
+
+[[clang::speculative_load_hardening]] void cf1();
+[[clang::speculative_load_hardening(1)]] void cf2(); // expected-error {{'speculative_load_hardening' attribute takes no arguments}}
+
+template <typename T>
+[[clang::speculative_load_hardening]]
+void ctf1();
+
+int cf3(int c[[clang::speculative_load_hardening]], int); // expected-error {{'speculative_load_hardening' attribute only applies to functions}}
+
+struct CA {
+ int f [[clang::speculative_load_hardening]]; // expected-error {{'speculative_load_hardening' attribute only applies to functions}}
+ [[clang::speculative_load_hardening]] void mf1();
+ [[clang::speculative_load_hardening]] static void mf2();
+};
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 7ec157fb73c..fa85b6e6ee7 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -1643,19 +1643,15 @@ example:
``speculative_load_hardening``
This attribute indicates that
`Speculative Load Hardening <https://llvm.org/docs/SpeculativeLoadHardening.html>`_
- should be enabled for the function body. This is a best-effort attempt to
- mitigate all known speculative execution information leak vulnerabilities
- that are based on the fundamental principles of modern processors'
- speculative execution. These vulnerabilities are classified as "Spectre
- variant #1" vulnerabilities typically. Notably, this does not attempt to
- mitigate any vulnerabilities where the speculative execution and/or
- prediction devices of specific processors can be *completely* undermined
- (such as "Branch Target Injection", a.k.a, "Spectre variant #2"). Instead,
- this is a target-independent request to harden against the completely
- generic risk posed by speculative execution to incorrectly load secret data,
- making it available to some micro-architectural side-channel for information
- leak. For a processor without any speculative execution or predictors, this
- is expected to be a no-op.
+ should be enabled for the function body.
+
+ Speculative Load Hardening is a best-effort mitigation against
+ information leak attacks that make use of control flow
+ miss-speculation - specifically miss-speculation of whether a branch
+ is taken or not. Typically vulnerabilities enabling such attacks are
+ classified as "Spectre variant #1". Notably, this does not attempt to
+ mitigate against miss-speculation of branch target, classified as
+ "Spectre variant #2" vulnerabilities.
When inlining, the attribute is sticky. Inlining a function that carries
this attribute will cause the caller to gain the attribute. This is intended
OpenPOWER on IntegriCloud