r351565 - [clang][slh] add Clang attr no_speculative_load_hardening

Zola Bridges via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 18 09:20:47 PST 2019


Author: zbrid
Date: Fri Jan 18 09:20:46 2019
New Revision: 351565

URL: http://llvm.org/viewvc/llvm-project?rev=351565&view=rev
Log:
[clang][slh] add Clang attr no_speculative_load_hardening

Summary:
This attribute will allow users to opt specific functions out of
speculative load hardening. This compliments the Clang attribute
named speculative_load_hardening. When this attribute or the attribute
speculative_load_hardening is used in combination with the flags
-mno-speculative-load-hardening or -mspeculative-load-hardening,
the function level attribute will override the default during LLVM IR
generation. For example, in the case, where the flag opposes the
function attribute, the function attribute will take precendence.
The sticky inlining behavior of the speculative_load_hardening attribute
may cause a function with the no_speculative_load_hardening attribute
to be tagged with the speculative_load_hardening tag in
subsequent compiler phases which is desired behavior since the
speculative_load_hardening LLVM attribute is designed to be maximally
conservative.

If both attributes are specified for a function, then an error will be
thrown.

Reviewers: chandlerc, echristo, kristof.beyls, aaron.ballman

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D54909

Added:
    cfe/trunk/test/CodeGenCXX/attr-speculative-load-hardening.cpp
    cfe/trunk/test/CodeGenObjC/attr-speculative-load-hardening.m
    cfe/trunk/test/SemaCXX/attr-no-speculative-load-hardening.cpp
Removed:
    cfe/trunk/test/CodeGen/attr-speculative-load-hardening.cpp
    cfe/trunk/test/CodeGen/attr-speculative-load-hardening.m
Modified:
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/AttrDocs.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test
    cfe/trunk/test/SemaCXX/attr-speculative-load-hardening.cpp

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=351565&r1=351564&r2=351565&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Fri Jan 18 09:20:46 2019
@@ -3149,6 +3149,12 @@ def SpeculativeLoadHardening : Inheritab
   let Documentation = [SpeculativeLoadHardeningDocs];
 }
 
+def NoSpeculativeLoadHardening : InheritableAttr {
+  let Spellings = [Clang<"no_speculative_load_hardening">];
+  let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
+  let Documentation = [NoSpeculativeLoadHardeningDocs];
+}
+
 def Uninitialized : InheritableAttr {
   let Spellings = [Clang<"uninitialized", 0>];
   let Subjects = SubjectList<[LocalVar]>;

Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=351565&r1=351564&r2=351565&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Fri Jan 18 09:20:46 2019
@@ -3822,7 +3822,8 @@ def SpeculativeLoadHardeningDocs : Docum
   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.
+  in Objective C. This attribute will take precedence over the command line flag in
+  the case where `-mno-speculative-load-hardening <https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mspeculative-load-hardening>`_ is specified.
 
   Speculative Load Hardening is a best-effort mitigation against
   information leak attacks that make use of control flow
@@ -3840,6 +3841,42 @@ def SpeculativeLoadHardeningDocs : Docum
   }];
 }
 
+def NoSpeculativeLoadHardeningDocs : 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>`_
+  is *not* needed for the function body. This can also be applied to a method
+  in Objective C. This attribute will take precedence over the command line flag in
+  the case where `-mspeculative-load-hardening <https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mspeculative-load-hardening>`_ is specified.
+
+  Warning: This attribute may not prevent Speculative Load Hardening from being
+  enabled for a function which inlines a function that has the
+  'speculative_load_hardening' attribute. This is intended to provide a
+  maximally conservative model where the code that is marked with the
+  'speculative_load_hardening' attribute will always (even when inlined)
+  be hardened. A user of this attribute may want to mark functions called by
+  a function they do not want to be hardened with the 'noinline' attribute.
+
+  For example:
+
+  .. code-block:: c
+
+    __attribute__((speculative_load_hardening))
+    int foo(int i) {
+      return i;
+    }
+
+    // Note: bar() may still have speculative load hardening enabled if
+    // foo() is inlined into bar(). Mark foo() with __attribute__((noinline))
+    // to avoid this situation.
+    __attribute__((no_speculative_load_hardening))
+    int bar(int i) {
+      return foo(i);
+    }
+  }];
+}
+
 def ObjCExternallyRetainedDocs : Documentation {
   let Category = DocCatVariable;
   let Content = [{

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=351565&r1=351564&r2=351565&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Jan 18 09:20:46 2019
@@ -2496,6 +2496,12 @@ public:
                                           unsigned AttrSpellingListIndex);
   MinSizeAttr *mergeMinSizeAttr(Decl *D, SourceRange Range,
                                 unsigned AttrSpellingListIndex);
+  NoSpeculativeLoadHardeningAttr *
+  mergeNoSpeculativeLoadHardeningAttr(Decl *D,
+                                      const NoSpeculativeLoadHardeningAttr &AL);
+  SpeculativeLoadHardeningAttr *
+  mergeSpeculativeLoadHardeningAttr(Decl *D,
+                                    const SpeculativeLoadHardeningAttr &AL);
   OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, SourceRange Range,
                                           unsigned AttrSpellingListIndex);
   InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL);

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=351565&r1=351564&r2=351565&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Fri Jan 18 09:20:46 2019
@@ -1793,8 +1793,6 @@ void CodeGenModule::ConstructDefaultFnAt
     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);
   }
@@ -1864,8 +1862,6 @@ void CodeGenModule::ConstructAttributeLi
       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(
@@ -1910,6 +1906,16 @@ void CodeGenModule::ConstructAttributeLi
 
   ConstructDefaultFnAttrList(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
 
+  // This must run after constructing the default function attribute list
+  // to ensure that the speculative load hardening attribute is removed
+  // in the case where the -mspeculative-load-hardening flag was passed.
+  if (TargetDecl) {
+    if (TargetDecl->hasAttr<NoSpeculativeLoadHardeningAttr>())
+      FuncAttrs.removeAttribute(llvm::Attribute::SpeculativeLoadHardening);
+    if (TargetDecl->hasAttr<SpeculativeLoadHardeningAttr>())
+      FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
+  }
+
   if (CodeGenOpts.EnableSegmentedStacks &&
       !(TargetDecl && TargetDecl->hasAttr<NoSplitStackAttr>()))
     FuncAttrs.addAttribute("split-stack");

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=351565&r1=351564&r2=351565&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Jan 18 09:20:46 2019
@@ -2489,6 +2489,10 @@ static bool mergeDeclAttribute(Sema &S,
   else if (const auto *UA = dyn_cast<UuidAttr>(Attr))
     NewAttr = S.mergeUuidAttr(D, UA->getRange(), AttrSpellingListIndex,
                               UA->getGuid());
+  else if (const auto *SLHA = dyn_cast<SpeculativeLoadHardeningAttr>(Attr))
+    NewAttr = S.mergeSpeculativeLoadHardeningAttr(D, *SLHA);
+  else if (const auto *SLHA = dyn_cast<NoSpeculativeLoadHardeningAttr>(Attr))
+    NewAttr = S.mergeNoSpeculativeLoadHardeningAttr(D, *SLHA);
   else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
     NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));
 

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=351565&r1=351564&r2=351565&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Jan 18 09:20:46 2019
@@ -4157,6 +4157,15 @@ MinSizeAttr *Sema::mergeMinSizeAttr(Decl
   return ::new (Context) MinSizeAttr(Range, Context, AttrSpellingListIndex);
 }
 
+NoSpeculativeLoadHardeningAttr *Sema::mergeNoSpeculativeLoadHardeningAttr(
+    Decl *D, const NoSpeculativeLoadHardeningAttr &AL) {
+  if (checkAttrMutualExclusion<SpeculativeLoadHardeningAttr>(*this, D, AL))
+    return nullptr;
+
+  return ::new (Context) NoSpeculativeLoadHardeningAttr(
+      AL.getRange(), Context, AL.getSpellingListIndex());
+}
+
 OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D, SourceRange Range,
                                               unsigned AttrSpellingListIndex) {
   if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
@@ -4177,6 +4186,15 @@ OptimizeNoneAttr *Sema::mergeOptimizeNon
                                           AttrSpellingListIndex);
 }
 
+SpeculativeLoadHardeningAttr *Sema::mergeSpeculativeLoadHardeningAttr(
+    Decl *D, const SpeculativeLoadHardeningAttr &AL) {
+  if (checkAttrMutualExclusion<NoSpeculativeLoadHardeningAttr>(*this, D, AL))
+    return nullptr;
+
+  return ::new (Context) SpeculativeLoadHardeningAttr(
+      AL.getRange(), Context, AL.getSpellingListIndex());
+}
+
 static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   if (checkAttrMutualExclusion<NotTailCalledAttr>(S, D, AL))
     return;
@@ -6618,7 +6636,13 @@ static void ProcessDeclAttribute(Sema &S
     handleSectionAttr(S, D, AL);
     break;
   case ParsedAttr::AT_SpeculativeLoadHardening:
-    handleSimpleAttribute<SpeculativeLoadHardeningAttr>(S, D, AL);
+    handleSimpleAttributeWithExclusions<SpeculativeLoadHardeningAttr,
+                                        NoSpeculativeLoadHardeningAttr>(S, D,
+                                                                        AL);
+    break;
+  case ParsedAttr::AT_NoSpeculativeLoadHardening:
+    handleSimpleAttributeWithExclusions<NoSpeculativeLoadHardeningAttr,
+                                        SpeculativeLoadHardeningAttr>(S, D, AL);
     break;
   case ParsedAttr::AT_CodeSeg:
     handleCodeSegAttr(S, D, AL);

Removed: cfe/trunk/test/CodeGen/attr-speculative-load-hardening.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/attr-speculative-load-hardening.cpp?rev=351564&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/attr-speculative-load-hardening.cpp (original)
+++ cfe/trunk/test/CodeGen/attr-speculative-load-hardening.cpp (removed)
@@ -1,18 +0,0 @@
-// 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{{.*}} }

Removed: cfe/trunk/test/CodeGen/attr-speculative-load-hardening.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/attr-speculative-load-hardening.m?rev=351564&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/attr-speculative-load-hardening.m (original)
+++ cfe/trunk/test/CodeGen/attr-speculative-load-hardening.m (removed)
@@ -1,9 +0,0 @@
-// 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{{.*}} }

Added: cfe/trunk/test/CodeGenCXX/attr-speculative-load-hardening.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/attr-speculative-load-hardening.cpp?rev=351565&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/attr-speculative-load-hardening.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/attr-speculative-load-hardening.cpp Fri Jan 18 09:20:46 2019
@@ -0,0 +1,62 @@
+// Check that we correctly set or did not set the attribute for each function.
+// 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 correctly set or did not set the attribute on each function despite the
+// -mspeculative-load-hardening flag.
+// RUN: %clang_cc1 -mspeculative-load-hardening -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK3
+// RUN: %clang_cc1 -mspeculative-load-hardening -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK4
+
+
+// Check that we correctly set or did not set the attribute on each function despite the
+// -mno-speculative-load-hardening flag.
+// RUN: %clang -mno-speculative-load-hardening -S -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK5
+// RUN: %clang -mno-speculative-load-hardening -S -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK6
+
+
+[[clang::speculative_load_hardening]]
+int test1() {
+  return 42;
+}
+
+int __attribute__((speculative_load_hardening)) test2() {
+  return 42;
+}
+
+[[clang::no_speculative_load_hardening]]
+int test3() {
+  return 42;
+}
+
+int __attribute__((no_speculative_load_hardening)) test4() {
+  return 42;
+}
+// CHECK1: @{{.*}}test1{{.*}}[[SLH:#[0-9]+]]
+// CHECK1: @{{.*}}test3{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK1: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK1-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK2: @{{.*}}test2{{.*}}[[SLH:#[0-9]+]]
+// CHECK2: @{{.*}}test4{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK2: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK2-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK3: @{{.*}}test1{{.*}}[[SLH:#[0-9]+]]
+// CHECK3: @{{.*}}test3{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK3: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK3-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK4: @{{.*}}test2{{.*}}[[SLH:#[0-9]+]]
+// CHECK4: @{{.*}}test4{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK4: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK4-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK5: @{{.*}}test1{{.*}}[[SLH:#[0-9]+]]
+// CHECK5: @{{.*}}test3{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK5: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK5-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK6: @{{.*}}test2{{.*}}[[SLH:#[0-9]+]]
+// CHECK6: @{{.*}}test4{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK6: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK6-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }

Added: cfe/trunk/test/CodeGenObjC/attr-speculative-load-hardening.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/attr-speculative-load-hardening.m?rev=351565&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/attr-speculative-load-hardening.m (added)
+++ cfe/trunk/test/CodeGenObjC/attr-speculative-load-hardening.m Fri Jan 18 09:20:46 2019
@@ -0,0 +1,14 @@
+// RUN: %clang -emit-llvm %s -o - -S | FileCheck %s -check-prefix=SLH
+
+int main() __attribute__((speculative_load_hardening)) {
+  return 0;
+}
+
+int test() __attribute__((no_speculative_load_hardening)) {
+  return 0;
+}
+
+// SLH: @{{.*}}main{{.*}}[[SLH:#[0-9]+]]
+// SLH: @{{.*}}test{{.*}}[[NOSLH:#[0-9]+]]
+// SLH: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// SLH-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }

Modified: cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test?rev=351565&r1=351564&r2=351565&view=diff
==============================================================================
--- cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test (original)
+++ cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test Fri Jan 18 09:20:46 2019
@@ -80,6 +80,7 @@
 // CHECK-NEXT: NoMips16 (SubjectMatchRule_function)
 // CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global)
 // CHECK-NEXT: NoSanitizeSpecific (SubjectMatchRule_function, SubjectMatchRule_variable_is_global)
+// CHECK-NEXT: NoSpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method)
 // CHECK-NEXT: NoSplitStack (SubjectMatchRule_function)
 // CHECK-NEXT: NoStackProtector (SubjectMatchRule_function)
 // CHECK-NEXT: NoThreadSafetyAnalysis (SubjectMatchRule_function)

Added: cfe/trunk/test/SemaCXX/attr-no-speculative-load-hardening.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-no-speculative-load-hardening.cpp?rev=351565&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-no-speculative-load-hardening.cpp (added)
+++ cfe/trunk/test/SemaCXX/attr-no-speculative-load-hardening.cpp Fri Jan 18 09:20:46 2019
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+int i __attribute__((no_speculative_load_hardening)); // expected-error {{'no_speculative_load_hardening' attribute only applies to functions}}
+
+void f1() __attribute__((no_speculative_load_hardening));
+void f2() __attribute__((no_speculative_load_hardening(1))); // expected-error {{'no_speculative_load_hardening' attribute takes no arguments}}
+
+template <typename T>
+void tf1() __attribute__((no_speculative_load_hardening));
+
+int f3(int __attribute__((no_speculative_load_hardening)), int); // expected-error {{'no_speculative_load_hardening' attribute only applies to functions}}
+
+struct A {
+  int f __attribute__((no_speculative_load_hardening));  // expected-error {{'no_speculative_load_hardening' attribute only applies to functions}}
+  void mf1() __attribute__((no_speculative_load_hardening));
+  static void mf2() __attribute__((no_speculative_load_hardening));
+};
+
+int ci [[clang::no_speculative_load_hardening]]; // expected-error {{'no_speculative_load_hardening' attribute only applies to functions}}
+
+[[clang::no_speculative_load_hardening]] void cf1();
+[[clang::no_speculative_load_hardening(1)]] void cf2(); // expected-error {{'no_speculative_load_hardening' attribute takes no arguments}}
+
+template <typename T>
+[[clang::no_speculative_load_hardening]]
+void ctf1();
+
+int cf3(int c[[clang::no_speculative_load_hardening]], int); // expected-error {{'no_speculative_load_hardening' attribute only applies to functions}}
+
+struct CA {
+  int f [[clang::no_speculative_load_hardening]];  // expected-error {{'no_speculative_load_hardening' attribute only applies to functions}}
+  [[clang::no_speculative_load_hardening]] void mf1();
+  [[clang::no_speculative_load_hardening]] static void mf2();
+};

Modified: cfe/trunk/test/SemaCXX/attr-speculative-load-hardening.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-speculative-load-hardening.cpp?rev=351565&r1=351564&r2=351565&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-speculative-load-hardening.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-speculative-load-hardening.cpp Fri Jan 18 09:20:46 2019
@@ -16,6 +16,17 @@ struct A {
   static void mf2() __attribute__((speculative_load_hardening));
 };
 
+void f4() __attribute__((no_speculative_load_hardening, speculative_load_hardening)); // expected-error {{attributes are not compatible}}
+// expected-note at -1 {{conflicting attribute is here}}
+
+void f5() __attribute__((speculative_load_hardening, no_speculative_load_hardening)); // expected-error {{attributes are not compatible}}
+// expected-note at -1 {{conflicting attribute is here}}
+
+void f6() __attribute__((no_speculative_load_hardening));
+
+void f6() __attribute__((speculative_load_hardening)); // expected-error at -2 {{'no_speculative_load_hardening' and 'speculative_load_hardening' attributes are not compatible}}
+// expected-note at -1 {{conflicting attribute is here}}
+
 int ci [[clang::speculative_load_hardening]]; // expected-error {{'speculative_load_hardening' attribute only applies to functions}}
 
 [[clang::speculative_load_hardening]] void cf1();
@@ -32,3 +43,16 @@ struct CA {
   [[clang::speculative_load_hardening]] void mf1();
   [[clang::speculative_load_hardening]] static void mf2();
 };
+
+[[clang::speculative_load_hardening, clang::no_speculative_load_hardening]] void cf4();  // expected-error {{attributes are not compatible}}
+// expected-note at -1 {{conflicting attribute is here}}
+
+[[clang::no_speculative_load_hardening, clang::speculative_load_hardening]] void cf5();  // expected-error {{attributes are not compatible}}
+// expected-note at -1 {{conflicting attribute is here}}
+
+[[clang::speculative_load_hardening]]
+void cf6();
+
+[[clang::no_speculative_load_hardening]]
+void cf6(); // expected-error at -4 {{'speculative_load_hardening' and 'no_speculative_load_hardening' attributes are not compatible}} \
+// expected-note at -1 {{conflicting attribute is here}}




More information about the cfe-commits mailing list