Files
RedBear-OS/local/recipes/dev/libclc/source/clang/test/Sema/attr-nonblocking-syntax.cpp
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

218 lines
8.3 KiB
C++

// RUN: %clang_cc1 %s -ast-dump -fblocks | FileCheck %s
// Make sure that the attribute gets parsed and attached to the correct AST elements.
#pragma clang diagnostic ignored "-Wunused-variable"
#pragma clang diagnostic ignored "-Wperf-constraint-implies-noexcept"
// =========================================================================================
// Square brackets, true
namespace square_brackets {
// 1. On the type of the FunctionDecl
void nl_function() [[clang::nonblocking]];
// CHECK: FunctionDecl {{.*}} nl_function 'void () __attribute__((nonblocking))'
// 2. On the type of the VarDecl holding a function pointer
void (*nl_func_a)() [[clang::nonblocking]];
// CHECK: VarDecl {{.*}} nl_func_a 'void (*)() __attribute__((nonblocking))'
// 3. On the type of the ParmVarDecl of a function parameter
static void nlReceiver(void (*nl_func)() [[clang::nonblocking]]);
// CHECK: ParmVarDecl {{.*}} nl_func 'void (*)() __attribute__((nonblocking))'
// 4. As an AttributedType within the nested types of a typedef
typedef void (*nl_fp_type)() [[clang::nonblocking]];
// CHECK: TypedefDecl {{.*}} nl_fp_type 'void (*)() __attribute__((nonblocking))'
using nl_fp_talias = void (*)() [[clang::nonblocking]];
// CHECK: TypeAliasDecl {{.*}} nl_fp_talias 'void (*)() __attribute__((nonblocking))'
// 5. From a typedef or typealias, on a VarDecl
nl_fp_type nl_fp_var1;
// CHECK: VarDecl {{.*}} nl_fp_var1 'nl_fp_type':'void (*)() __attribute__((nonblocking))'
nl_fp_talias nl_fp_var2;
// CHECK: VarDecl {{.*}} nl_fp_var2 'nl_fp_talias':'void (*)() __attribute__((nonblocking))'
// 6. On type of a FieldDecl
struct Struct {
void (*nl_func_field)() [[clang::nonblocking]];
// CHECK: FieldDecl {{.*}} nl_func_field 'void (*)() __attribute__((nonblocking))'
};
// nonallocating should NOT be subsumed into nonblocking
void nl1() [[clang::nonblocking]] [[clang::nonallocating]];
// CHECK: FunctionDecl {{.*}} nl1 'void () __attribute__((nonblocking)) __attribute__((nonallocating))'
void nl2() [[clang::nonallocating]] [[clang::nonblocking]];
// CHECK: FunctionDecl {{.*}} nl2 'void () __attribute__((nonblocking)) __attribute__((nonallocating))'
decltype(nl1) nl3;
// CHECK: FunctionDecl {{.*}} nl3 'decltype(nl1)':'void () __attribute__((nonblocking)) __attribute__((nonallocating))'
// Attribute propagates from base class virtual method to overrides.
struct Base {
virtual void nb_method() [[clang::nonblocking]];
};
struct Derived : public Base {
void nb_method() override;
// CHECK: CXXMethodDecl {{.*}} nb_method 'void () __attribute__((nonblocking))'
};
// Dependent expression
template <bool V>
struct Dependent {
void nb_method2() [[clang::nonblocking(V)]];
// CHECK: CXXMethodDecl {{.*}} nb_method2 'void () __attribute__((nonblocking(V)))'
};
// --- Blocks ---
// On the type of the VarDecl holding a BlockDecl
void (^nl_block1)() [[clang::nonblocking]] = ^() [[clang::nonblocking]] {};
// CHECK: VarDecl {{.*}} nl_block1 'void (^)() __attribute__((nonblocking))'
int (^nl_block2)() [[clang::nonblocking]] = ^() [[clang::nonblocking]] { return 0; };
// CHECK: VarDecl {{.*}} nl_block2 'int (^)() __attribute__((nonblocking))'
// The operand of the CallExpr is an ImplicitCastExpr of a DeclRefExpr -> nl_block which hold the attribute
static void blockCaller() { nl_block1(); }
// CHECK: DeclRefExpr {{.*}} 'nl_block1' 'void (^)() __attribute__((nonblocking))'
// --- Lambdas ---
// On the operator() of a lambda's CXXMethodDecl
auto nl_lambda = []() [[clang::nonblocking]] {};
// CHECK: CXXMethodDecl {{.*}} operator() 'void () const __attribute__((nonblocking))' inline
// =========================================================================================
// Square brackets, false
void nl_func_false() [[clang::blocking]];
// CHECK: FunctionDecl {{.*}} nl_func_false 'void () __attribute__((blocking))'
auto nl_lambda_false = []() [[clang::blocking]] {};
// CHECK: CXXMethodDecl {{.*}} operator() 'void () const __attribute__((blocking))'
} // namespace square_brackets
// =========================================================================================
// GNU-style attribute, true
namespace gnu_style {
// 1. On the type of the FunctionDecl
void nl_function() __attribute__((nonblocking));
// CHECK: FunctionDecl {{.*}} nl_function 'void () __attribute__((nonblocking))'
// 1a. Alternate placement on the FunctionDecl
__attribute__((nonblocking)) void nl_function();
// CHECK: FunctionDecl {{.*}} nl_function 'void () __attribute__((nonblocking))'
// 2. On the type of the VarDecl holding a function pointer
void (*nl_func_a)() __attribute__((nonblocking));
// CHECK: VarDecl {{.*}} nl_func_a 'void (*)() __attribute__((nonblocking))'
// 2a. Alternate attribute placement on VarDecl
__attribute__((nonblocking)) void (*nl_func_b)();
// CHECK: VarDecl {{.*}} nl_func_b 'void (*)() __attribute__((nonblocking))'
// 3. On the type of the ParmVarDecl of a function parameter
static void nlReceiver(void (*nl_func)() __attribute__((nonblocking)));
// CHECK: ParmVarDecl {{.*}} nl_func 'void (*)() __attribute__((nonblocking))'
// 4. As an AttributedType within the nested types of a typedef
// Note different placement from square brackets for the typealias.
typedef void (*nl_fp_type)() __attribute__((nonblocking));
// CHECK: TypedefDecl {{.*}} nl_fp_type 'void (*)() __attribute__((nonblocking))'
using nl_fp_talias = __attribute__((nonblocking)) void (*)();
// CHECK: TypeAliasDecl {{.*}} nl_fp_talias 'void (*)() __attribute__((nonblocking))'
// 5. From a typedef or typealias, on a VarDecl
nl_fp_type nl_fp_var1;
// CHECK: VarDecl {{.*}} nl_fp_var1 'nl_fp_type':'void (*)() __attribute__((nonblocking))'
nl_fp_talias nl_fp_var2;
// CHECK: VarDecl {{.*}} nl_fp_var2 'nl_fp_talias':'void (*)() __attribute__((nonblocking))'
// 6. On type of a FieldDecl
struct Struct {
void (*nl_func_field)() __attribute__((nonblocking));
// CHECK: FieldDecl {{.*}} nl_func_field 'void (*)() __attribute__((nonblocking))'
};
} // namespace gnu_style
// =========================================================================================
// nonallocating and allocating - quick checks because the code paths are generally
// identical after parsing.
void na_function() [[clang::nonallocating]];
// CHECK: FunctionDecl {{.*}} na_function 'void () __attribute__((nonallocating))'
void na_true_function() [[clang::nonallocating(true)]];
// CHECK: FunctionDecl {{.*}} na_true_function 'void () __attribute__((nonallocating))'
void na_false_function() [[clang::nonallocating(false)]];
// CHECK: FunctionDecl {{.*}} na_false_function 'void () __attribute__((allocating))'
void alloc_function() [[clang::allocating]];
// CHECK: FunctionDecl {{.*}} alloc_function 'void () __attribute__((allocating))'
// =========================================================================================
// Non-blocking with an expression parameter
void t0() [[clang::nonblocking(1 - 1)]];
// CHECK: FunctionDecl {{.*}} t0 'void () __attribute__((blocking))'
void t1() [[clang::nonblocking(1 + 1)]];
// CHECK: FunctionDecl {{.*}} t1 'void () __attribute__((nonblocking))'
template <bool V>
struct ValueDependent {
void nb_method() [[clang::nonblocking(V)]];
};
void t3() [[clang::nonblocking]]
{
ValueDependent<false> x1;
x1.nb_method();
// CHECK: ClassTemplateSpecializationDecl {{.*}} ValueDependent
// CHECK: TemplateArgument integral 'false'
// CHECK: CXXMethodDecl {{.*}} nb_method 'void () __attribute__((blocking))'
ValueDependent<true> x2;
x2.nb_method();
// CHECK: ClassTemplateSpecializationDecl {{.*}} ValueDependent
// CHECK: TemplateArgument integral 'true'
// CHECK: CXXMethodDecl {{.*}} nb_method 'void () __attribute__((nonblocking))'
}
template <typename X>
struct TypeDependent {
void td_method() [[clang::nonblocking(X::is_nb)]];
};
struct NBPolicyTrue {
static constexpr bool is_nb = true;
};
struct NBPolicyFalse {
static constexpr bool is_nb = false;
};
void t4()
{
TypeDependent<NBPolicyFalse> x1;
x1.td_method();
// CHECK: ClassTemplateSpecializationDecl {{.*}} TypeDependent
// CHECK: TemplateArgument type 'NBPolicyFalse'
// CHECK: CXXMethodDecl {{.*}} td_method 'void () __attribute__((blocking))'
TypeDependent<NBPolicyTrue> x2;
x2.td_method();
// CHECK: ClassTemplateSpecializationDecl {{.*}} TypeDependent
// CHECK: TemplateArgument type 'NBPolicyTrue'
// CHECK: CXXMethodDecl {{.*}} td_method 'void () __attribute__((nonblocking))'
}