[clang] 9477869 - [clang] Add support for __attribute__((guard(nocf)))

Martin Storsjö via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 23 13:40:26 PDT 2022


Author: Alvin Wong
Date: 2022-08-23T23:39:38+03:00
New Revision: 94778692ad25456c9042caae96c40a7c066b6249

URL: https://github.com/llvm/llvm-project/commit/94778692ad25456c9042caae96c40a7c066b6249
DIFF: https://github.com/llvm/llvm-project/commit/94778692ad25456c9042caae96c40a7c066b6249.diff

LOG: [clang] Add support for __attribute__((guard(nocf)))

To support using Control Flow Guard with mingw-w64, Clang needs to
accept `__declspec(guard(nocf))` also for the GNU target. Since mingw
has `#define __declspec(a) __attribute__((a))` as built-in, the simplest
solution is to accept `__attribute__((guard(nocf)))` to be compatible with
MSVC and Clang's msvc target.

As a side effect, this also adds `[[clang::guard(nocf)]]` for C++.

Reviewed By: aaron.ballman

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

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/Attr.td
    clang/test/CodeGen/guard_nocf.c
    clang/test/CodeGenCXX/guard_nocf.cpp
    clang/test/Misc/pragma-attribute-supported-attributes-list.test
    clang/test/Sema/attr-guard_nocf.c

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 90cb8a60d3ac..6109f4e8ac6b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -128,6 +128,11 @@ New Pragmas in Clang
 
 Attribute Changes in Clang
 --------------------------
+- Added support for ``__attribute__((guard(nocf)))`` and C++-style
+  ``[[clang::guard(nocf)]]``, which is equivalent to ``__declspec(guard(nocf))``
+  when using the MSVC environment. This is to support enabling Windows Control
+  Flow Guard checks with the ability to disable them for specific functions when
+  using the MinGW environment.
 
 Windows Support
 ---------------

diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index e504596a2067..129055982c54 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3494,7 +3494,7 @@ def MSAllocator : InheritableAttr {
 def CFGuard : InheritableAttr {
   // Currently only the __declspec(guard(nocf)) modifier is supported. In future
   // we might also want to support __declspec(guard(suppress)).
-  let Spellings = [Declspec<"guard">];
+  let Spellings = [Declspec<"guard">, Clang<"guard">];
   let Subjects = SubjectList<[Function]>;
   let Args = [EnumArgument<"Guard", "GuardArg", ["nocf"], ["nocf"]>];
   let Documentation = [CFGuardDocs];

diff  --git a/clang/test/CodeGen/guard_nocf.c b/clang/test/CodeGen/guard_nocf.c
index 57013c4e2638..0d66f7ff1bd9 100644
--- a/clang/test/CodeGen/guard_nocf.c
+++ b/clang/test/CodeGen/guard_nocf.c
@@ -1,4 +1,8 @@
 // RUN: %clang_cc1 -triple %ms_abi_triple -fms-extensions -emit-llvm -O2 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-w64-windows-gnu -emit-llvm -O2 -o - %s | FileCheck %s
+
+// The x86_64-w64-windows-gnu version tests mingw target, which relies on
+// __declspec(...) being defined as __attribute__((...)) by compiler built-in.
 
 void target_func(void);
 void (*func_ptr)(void) = &target_func;
@@ -10,6 +14,15 @@ __declspec(guard(nocf)) void nocf0(void) {
 // CHECK-LABEL: nocf0
 // CHECK: call{{.*}}[[NOCF:#[0-9]+]]
 
+// Explicitly test using the GNU-style attribute without relying on the
+// __declspec define for mingw.
+// The "guard_nocf" attribute must be added.
+__attribute__((guard(nocf))) void nocf0_gnu_style(void) {
+  (*func_ptr)();
+}
+// CHECK-LABEL: nocf0_gnu_style
+// CHECK: call{{.*}}[[NOCF:#[0-9]+]]
+
 // The "guard_nocf" attribute must *not* be added.
 void cf0(void) {
   (*func_ptr)();

diff  --git a/clang/test/CodeGenCXX/guard_nocf.cpp b/clang/test/CodeGenCXX/guard_nocf.cpp
index 3dc5c50b6bfd..ad434b73499a 100644
--- a/clang/test/CodeGenCXX/guard_nocf.cpp
+++ b/clang/test/CodeGenCXX/guard_nocf.cpp
@@ -1,4 +1,8 @@
 // RUN: %clang_cc1 -triple %ms_abi_triple -fms-extensions -std=c++11 -emit-llvm -O2 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-w64-windows-gnu -std=c++11 -emit-llvm -O2 -o - %s | FileCheck %s
+
+// The x86_64-w64-windows-gnu version tests mingw target, which relies on
+// __declspec(...) being defined as __attribute__((...)) by compiler built-in.
 
 void target_func();
 void (*func_ptr)() = &target_func;
@@ -10,6 +14,23 @@ __declspec(guard(nocf)) void nocf0() {
 // CHECK-LABEL: nocf0
 // CHECK: call{{.*}}[[NOCF:#[0-9]+]]
 
+// Explicitly test using the GNU-style attribute without relying on the
+// __declspec define for mingw.
+// The "guard_nocf" attribute must be added.
+__attribute__((guard(nocf))) void nocf0_gnu_style() {
+  (*func_ptr)();
+}
+// CHECK-LABEL: nocf0_gnu_style
+// CHECK: call{{.*}}[[NOCF:#[0-9]+]]
+
+// Test using the c++-style attribute.
+// The "guard_nocf" attribute must be added.
+[[clang::guard(nocf)]] void nocf0_cxx_style() {
+  (*func_ptr)();
+}
+// CHECK-LABEL: nocf0_cxx_style
+// CHECK: call{{.*}}[[NOCF:#[0-9]+]]
+
 // The "guard_nocf" attribute must *not* be added.
 void cf0() {
   (*func_ptr)();

diff  --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index d6e1538bd92a..bde950500993 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -26,6 +26,7 @@
 // CHECK-NEXT: BuiltinAlias (SubjectMatchRule_function)
 // CHECK-NEXT: CFAuditedTransfer (SubjectMatchRule_function)
 // CHECK-NEXT: CFConsumed (SubjectMatchRule_variable_is_parameter)
+// CHECK-NEXT: CFGuard (SubjectMatchRule_function)
 // CHECK-NEXT: CFICanonicalJumpTable (SubjectMatchRule_function)
 // CHECK-NEXT: CFUnknownTransfer (SubjectMatchRule_function)
 // CHECK-NEXT: CPUDispatch (SubjectMatchRule_function)

diff  --git a/clang/test/Sema/attr-guard_nocf.c b/clang/test/Sema/attr-guard_nocf.c
index 6f01970b8da3..7d7708e76647 100644
--- a/clang/test/Sema/attr-guard_nocf.c
+++ b/clang/test/Sema/attr-guard_nocf.c
@@ -1,10 +1,20 @@
 // RUN: %clang_cc1 -triple %ms_abi_triple -fms-extensions -verify -fsyntax-only %s
 // RUN: %clang_cc1 -triple %ms_abi_triple -fms-extensions -verify -std=c++11 -fsyntax-only -x c++ %s
+// RUN: %clang_cc1 -triple x86_64-w64-windows-gnu -verify -fsyntax-only %s
+// RUN: %clang_cc1 -triple x86_64-w64-windows-gnu -verify -std=c++11 -fsyntax-only -x c++ %s
+
+// The x86_64-w64-windows-gnu version tests mingw target, which relies on
+// __declspec(...) being defined as __attribute__((...)) by compiler built-in.
 
 // Function definition.
 __declspec(guard(nocf)) void testGuardNoCF(void) { // no warning
 }
 
+// Function definition using GNU-style attribute without relying on the
+// __declspec define for mingw.
+__attribute__((guard(nocf))) void testGNUStyleGuardNoCF(void) { // no warning
+}
+
 // Can not be used on variable, parameter, or function pointer declarations.
 int __declspec(guard(nocf)) i;                                      // expected-warning {{'guard' attribute only applies to functions}}
 void testGuardNoCFFuncParam(double __declspec(guard(nocf)) i) {}    // expected-warning {{'guard' attribute only applies to functions}}


        


More information about the cfe-commits mailing list