We would previously reject valid input where GNU attributes preceded the standard attributes on top-level declarations. A previous attribute handling change had begun rejecting this whilst GCC does honour this layout. In practice, this breaks use of `extern "C"` attributed functions which use both standard and GNU attributes as experienced by the Swift runtime. Objective-C deserves an honourable mention for requiring some additional special casing. Because attributes on declarations and definitions differ in semantics, we need to replicate some of the logic for detecting attributes to declarations to which they appertain cannot be attributed. This should match the existing case for the application of GNU attributes to interfaces, protocols, and implementations. Take the opportunity to split out the tooling tests into two cases: ones which process macros and ones which do not. Special thanks to Aaron Ballman for the many hints and extensive rubber ducking that was involved in identifying the various places where we accidentally dropped attributes. Differential Revision: https://reviews.llvm.org/D137979 Fixes: #58229 Reviewed By: aaron.ballman, arphaman
25 lines
1.5 KiB
C++
25 lines
1.5 KiB
C++
// RUN: %clang_cc1 -fsyntax-only -fms-extensions -Wno-ignored-attributes -verify %s
|
|
|
|
struct [[]] __attribute__((lockable)) __declspec(dllexport) A {}; // ok
|
|
struct [[]] __declspec(dllexport) __attribute__((lockable)) B {}; // ok
|
|
struct [[]] [[]] __declspec(dllexport) __attribute__((lockable)) C {}; // ok
|
|
struct __declspec(dllexport) [[]] __attribute__((lockable)) D {}; // ok
|
|
struct __declspec(dllexport) __attribute__((lockable)) [[]] E {}; // ok
|
|
struct __attribute__((lockable)) __declspec(dllexport) [[]] F {}; // ok
|
|
struct __attribute__((lockable)) [[]] __declspec(dllexport) G {}; // ok
|
|
struct [[]] __attribute__((lockable)) [[]] __declspec(dllexport) H {}; // ok
|
|
|
|
[[noreturn]] __attribute__((cdecl)) __declspec(dllexport) void a(); // ok
|
|
[[noreturn]] __declspec(dllexport) __attribute__((cdecl)) void b(); // ok
|
|
[[]] [[noreturn]] __attribute__((cdecl)) __declspec(dllexport) void c(); // ok
|
|
|
|
// [[]] attributes before a declaration must be at the start of the line.
|
|
__declspec(dllexport) [[noreturn]] __attribute__((cdecl)) void d(); // expected-error {{an attribute list cannot appear here}}
|
|
__declspec(dllexport) __attribute__((cdecl)) [[noreturn]] void e(); // expected-error {{an attribute list cannot appear here}}
|
|
__attribute__((cdecl)) __declspec(dllexport) [[noreturn]] void f(); // expected-error {{an attribute list cannot appear here}}
|
|
__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void g();
|
|
|
|
[[noreturn]] __attribute__((cdecl))
|
|
[[]]
|
|
__declspec(dllexport) void h();
|