Files
RedBear-OS/local/recipes/dev/libclc/source/clang/test/Parser/ms-square-bracket-attributes.mm
T
vasilito cb424d7448 build: static patch-sanity linter (shift-left the malformed-patch class)
verify-patch-sanity.py validates every active recipe .patch has internally-
consistent hunk line counts — catching the 'malformed patch at line N' failure
at commit/CI/preflight time instead of hours into a cook. This cycle hit that
class three times (qtwaylandscanner, sddm, xwayland), each only discovered when
cookbook tried to apply the patch.

Running it across the repo found 29 latent malformed patches (validated against
GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22').
They were harmless only because they sit in vendored recipes (baked, not re-
applied) — but would fail on any version-bump re-derivation. --fix recounts the
hunk headers (body untouched) and repaired all 29.

Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test
(test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats
(empty placeholders, bare-@@ git hunks).
2026-08-01 05:13:02 +03:00

175 lines
7.3 KiB
Plaintext

// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify -fms-extensions %s -Wno-deprecated-declarations
typedef struct _GUID {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;
namespace {
// cl.exe supports [] attributes on decls like so:
[uuid( "000000A0-0000-0000-C000-000000000049" )] struct struct_with_uuid;
// Optionally, the uuid can be surrounded by one set of braces.
[uuid(
"{000000A0-0000-0000-C000-000000000049}"
)] struct struct_with_uuid_brace;
// uuids must be ascii string literals.
// expected-warning@+1 {{encoding prefix 'u8' on an unevaluated string literal has no effect and is incompatible with c++2c}}
[uuid(u8"000000A0-0000-0000-C000-000000000049")] struct struct_with_uuid_u8;
// expected-warning@+1 {{encoding prefix 'L' on an unevaluated string literal has no effect and is incompatible with c++2c}}
[uuid(L"000000A0-0000-0000-C000-000000000049")] struct struct_with_uuid_L;
// cl.exe doesn't allow raw string literals in []-style attributes, but does
// allow it for __declspec(uuid()) (u8 literals etc are not allowed there
// either). Since raw string literals not being allowed seems like an
// implementation artifact in cl and not allowing them makes the parse code
// a bit unnatural, do allow this.
[uuid(R"(000000A0-0000-0000-C000-000000000049)")] struct struct_with_uuid_raw;
// Likewise, cl supports UCNs in declspec uuid, but not in []-style uuid.
// clang-cl allows them in both.
[uuid("000000A0-0000\u002D0000-C000-000000000049")] struct struct_with_uuid_ucn;
// cl doesn't allow string concatenation in []-style attributes, for no good
// reason. clang-cl allows them.
[uuid("000000A0-00" "00-0000-C000-000000000049")] struct struct_with_uuid_split;
// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
[uuid("{000000A0-0000-0000-C000-000000000049}", "1")] struct S {};
// expected-error@+1 {{expected '('}}
[uuid{"000000A0-0000-0000-C000-000000000049"}] struct T {};
// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
[uuid("000000A0-0000-0000-C000-000000000049"}] struct U {};
// In addition to uuids in string literals, cl also allows uuids that are not
// in a string literal, only delimited by (). The contents of () are almost
// treated like a literal (spaces there aren't ignored), but macro substitution,
// \ newline escapes, and so on are performed.
[ uuid (000000A0-0000-0000-C000-000000000049) ] struct struct_with_uuid2;
[uuid({000000A0-0000-0000-C000-000000000049})] struct struct_with_uuid2_brace;
// The non-quoted form doesn't allow any whitespace inside the parens:
// expected-error@+1 {{uuid attribute contains a malformed GUID}}
[uuid( 000000A0-0000-0000-C000-000000000049)] struct struct_with_uuid2;
// expected-error@+1 {{uuid attribute contains a malformed GUID}}
[uuid(000000A0-0000 -0000-C000-000000000049)] struct struct_with_uuid2;
// expected-error@+2 {{uuid attribute contains a malformed GUID}}
[uuid(000000A0-0000
-0000-C000-000000000049)] struct struct_with_uuid2;
// expected-error@+1 {{uuid attribute contains a malformed GUID}}
[uuid(000000A0-0000/**/-0000-C000-000000000049)] struct struct_with_uuid2;
// expected-error@+1 {{uuid attribute contains a malformed GUID}}
[uuid(000000A0-0000-0000-C000-000000000049 )] struct struct_with_uuid2;
// expected-error@+2 {{uuid attribute contains a malformed GUID}}
[uuid(000000A0-0000-0000-C000-000000000049
)
] struct struct_with_uuid2;
// expected-error@+1 {{uuid attribute contains a malformed GUID}}
[uuid({000000A0-0000-""0000-C000-000000000049})] struct struct_with_uuid2;
// Line continuations and macro substitution are fine though:
[uuid(000000A0-0000-0000-\
C000-000000000049)] struct struct_with_uuid2_cont;
#define UUID 000000A0-0000-0000-C000-000000000049
#define UUID_PART 000000A0-0000
[uuid(UUID)] struct struct_with_uuid2_macro;
[uuid(UUID_PART-0000-C000-000000000049)] struct struct_with_uuid2_macro_part;
// Both cl and clang-cl accept trigraphs here (with /Zc:trigraphs, off by
// default)
// expected-warning@+1 2{{trigraph converted}}
[uuid(??<000000A0-0000-0000-C000-000000000049??>)]
struct struct_with_uuid2_trigraph;
// UCNs cannot be used in this form because they're prohibited by C99.
// expected-error@+1 {{character '-' cannot be specified by a universal character name}}
[uuid(000000A0-0000\u002D0000-C000-000000000049)] struct struct_with_uuid2_ucn;
// Invalid digits.
// expected-error@+1 {{uuid attribute contains a malformed GUID}}
[uuid(0Z0000A0-0000-0000-C000-000000000049)] struct struct_with_uuid2;
struct OuterClass {
// [] uuids and inner classes are weird in cl.exe: It warns that uuid on
// nested types has undefined behavior, and errors out __uuidof() claiming
// that the inner type has no assigned uuid. Things work fine if __declspec()
// is used instead. clang-cl handles this fine.
[uuid(10000000-0000-0000-0000-000000000000)] class InnerClass1;
[uuid(10000000-0000-0000-0000-000000000000)] class InnerClass2 {} ic;
[uuid(10000000-0000-0000-0000-000000000000)] static class InnerClass3 {} sic;
// Putting `static` in front of [...] causes parse errors in both cl and clang
// This is the only syntax to declare an inner class with []-style attributes
// that works in cl: Declare the inner class without an attribute, and then
// have the []-style attribute on the definition.
class InnerClass;
};
[uuid(10000000-0000-0000-0000-000000000000)] class OuterClass::InnerClass {};
void use_it() {
(void)__uuidof(struct_with_uuid);
(void)__uuidof(struct_with_uuid_brace);
(void)__uuidof(struct_with_uuid_raw);
(void)__uuidof(struct_with_uuid_ucn);
(void)__uuidof(struct_with_uuid_split);
(void)__uuidof(struct_with_uuid2);
(void)__uuidof(struct_with_uuid2_brace);
(void)__uuidof(struct_with_uuid2_cont);
(void)__uuidof(struct_with_uuid2_macro);
(void)__uuidof(struct_with_uuid2_macro_part);
(void)__uuidof(struct_with_uuid2_trigraph);
(void)__uuidof(OuterClass::InnerClass);
(void)__uuidof(OuterClass::InnerClass1);
(void)__uuidof(OuterClass::InnerClass2);
(void)__uuidof(OuterClass::InnerClass3);
(void)__uuidof(OuterClass().ic);
(void)__uuidof(OuterClass::sic);
}
// expected-warning@+1 {{'uuid' attribute only applies to structs, unions, classes, and enums}}
[uuid("000000A0-0000-0000-C000-000000000049")] void f();
}
// clang supports these on toplevel decls, but not on local decls since this
// syntax is ambiguous with lambdas and Objective-C message send expressions.
// This file documents clang's shortcomings and lists a few constructs that
// one has to keep in mind when trying to fix this. System headers only seem
// to use these attributes on toplevel decls, so supporting this is not very
// important.
void local_class() {
// FIXME: MSVC accepts, but we reject due to ambiguity.
// expected-error@+1 {{expected body of lambda expression}}
[uuid("a5a7bd07-3b14-49bc-9399-de066d4d72cd")] struct Local {
int x;
};
}
void useit(int);
int lambda() {
int uuid = 42;
[uuid]() { useit(uuid); }();
// C++14 lambda init captures:
[uuid(00000000-0000-0000-0000-000000000000)] { return uuid; }();
[uuid("00000000-0000-0000-0000-000000000000")](int n) { return uuid[n]; }(3);
}
@interface NSObject
- (void)retain;
@end
int message_send(id uuid) {
[uuid retain];
}
NSObject* uuid(const char*);
int message_send2() {
[uuid("a5a7bd07-3b14-49bc-9399-de066d4d72cd") retain];
}