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}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits