1 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +bf16 -target-feature +sme -target-feature +sme2 -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify %s 2 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +bf16 -target-feature +sme -target-feature +sme2 -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify=expected-cpp -x c++ %s 3 4 // Valid attributes 5 6 void sme_arm_streaming(void) __arm_streaming; 7 void sme_arm_streaming_compatible(void) __arm_streaming_compatible; 8 9 __arm_new("za") void sme_arm_new_za(void) {} 10 void sme_arm_shared_za(void) __arm_inout("za"); 11 void sme_arm_preserves_za(void) __arm_preserves("za"); 12 void sme_arm_agnostic(void) __arm_agnostic("sme_za_state"); 13 14 __arm_new("za") void sme_arm_streaming_new_za(void) __arm_streaming {} 15 void sme_arm_streaming_shared_za(void) __arm_streaming __arm_inout("za"); 16 void sme_arm_streaming_preserves_za(void) __arm_streaming __arm_preserves("za"); 17 18 __arm_new("za") void sme_arm_sc_new_za(void) __arm_streaming_compatible {} 19 void sme_arm_sc_shared_za(void) __arm_streaming_compatible __arm_inout("za"); 20 void sme_arm_sc_preserves_za(void) __arm_streaming_compatible __arm_preserves("za"); 21 22 __arm_locally_streaming void sme_arm_locally_streaming(void) { } 23 __arm_locally_streaming void sme_arm_streaming_and_locally_streaming(void) __arm_streaming { } 24 __arm_locally_streaming void sme_arm_streaming_and_streaming_compatible(void) __arm_streaming_compatible { } 25 26 __arm_locally_streaming __arm_new("za") void sme_arm_ls_new_za(void) { } 27 __arm_locally_streaming void sme_arm_ls_shared_za(void) __arm_inout("za") { } 28 __arm_locally_streaming void sme_arm_ls_preserves_za(void) __arm_preserves("za") { } 29 30 // Valid attributes on function pointers 31 32 void streaming_ptr(void) __arm_streaming; 33 typedef void (*fptrty1) (void) __arm_streaming; 34 fptrty1 call_streaming_func() { return streaming_ptr; } 35 36 void streaming_compatible_ptr(void) __arm_streaming_compatible; 37 typedef void (*fptrty2) (void) __arm_streaming_compatible; 38 fptrty2 call_sc_func() { return streaming_compatible_ptr; } 39 40 void shared_za_ptr(void) __arm_inout("za"); 41 typedef void (*fptrty3) (void) __arm_inout("za"); 42 fptrty3 call_shared_za_func() { return shared_za_ptr; } 43 44 void preserves_za_ptr(void) __arm_preserves("za"); 45 typedef void (*fptrty4) (void) __arm_preserves("za"); 46 fptrty4 call_preserve_za_func() { return preserves_za_ptr; } 47 48 typedef void (*fptrty6) (void); 49 fptrty6 cast_nza_func_to_normal() { return sme_arm_new_za; } 50 fptrty6 cast_ls_func_to_normal() { return sme_arm_locally_streaming; } 51 52 // Invalid attributes 53 54 // expected-cpp-error@+4 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}} 55 // expected-cpp-note@+3 {{conflicting attribute is here}} 56 // expected-error@+2 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}} 57 // expected-note@+1 {{conflicting attribute is here}} 58 void streaming_mode(void) __arm_streaming __arm_streaming_compatible; 59 60 // expected-cpp-error@+4 {{'__arm_streaming' and '__arm_streaming_compatible' are not compatible}} 61 // expected-cpp-note@+3 {{conflicting attribute is here}} 62 // expected-error@+2 {{'__arm_streaming' and '__arm_streaming_compatible' are not compatible}} 63 // expected-note@+1 {{conflicting attribute is here}} 64 void streaming_compatible(void) __arm_streaming_compatible __arm_streaming; 65 66 // expected-cpp-error@+2 {{'__arm_new("za")' and '__arm_inout("za")' are not compatible}} 67 // expected-error@+1 {{'__arm_new("za")' and '__arm_inout("za")' are not compatible}} 68 __arm_new("za") void new_shared_za(void) __arm_inout("za") {} 69 70 // expected-cpp-error@+2 {{'__arm_new("za")' and '__arm_preserves("za")' are not compatible}} 71 // expected-error@+1 {{'__arm_new("za")' and '__arm_preserves("za")' are not compatible}} 72 __arm_new("za") void new_preserves_za(void) __arm_preserves("za") {} 73 74 // Invalid attributes on function pointers 75 76 // expected-cpp-error@+4 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}} 77 // expected-cpp-note@+3 {{conflicting attribute is here}} 78 // expected-error@+2 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}} 79 // expected-note@+1 {{conflicting attribute is here}} 80 void streaming_ptr_invalid(void) __arm_streaming __arm_streaming_compatible; 81 // expected-cpp-error@+4 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}} 82 // expected-cpp-note@+3 {{conflicting attribute is here}} 83 // expected-error@+2 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}} 84 // expected-note@+1 {{conflicting attribute is here}} 85 typedef void (*fptrty7) (void) __arm_streaming __arm_streaming_compatible; 86 fptrty7 invalid_streaming_func() { return streaming_ptr_invalid; } 87 88 // expected-warning@+2 {{'__arm_streaming' only applies to non-K&R-style functions}} 89 // expected-error@+1 {{'__arm_streaming' only applies to function types; type here is 'void ()'}} 90 void function_no_prototype() __arm_streaming; 91 92 // expected-cpp-error@+2 {{__arm_agnostic("sme_za_state") cannot share ZA state with its caller}} 93 // expected-error@+1 {{__arm_agnostic("sme_za_state") cannot share ZA state with its caller}} 94 void sme_arm_agnostic_shared_za_zt0(void) __arm_agnostic("sme_za_state") __arm_inout("zt0") {} 95 96 // expected-cpp-error@+2 {{__arm_agnostic("sme_za_state") cannot share ZA state with its caller}} 97 // expected-error@+1 {{__arm_agnostic("sme_za_state") cannot share ZA state with its caller}} 98 void sme_arm_agnostic_shared_za_za(void) __arm_agnostic("sme_za_state") __arm_inout("za") {} 99 100 // expected-cpp-error@+2 {{__arm_agnostic("sme_za_state") cannot share ZA state with its caller}} 101 // expected-error@+1 {{__arm_agnostic("sme_za_state") cannot share ZA state with its caller}} 102 void sme_arm_agnostic_shared_za_za_rev(void) __arm_inout("za") __arm_agnostic("sme_za_state") {} 103 104 // expected-cpp-error@+2 {{__arm_agnostic("sme_za_state") is not supported together with __arm_new("za") or __arm_new("zt0")}} 105 // expected-error@+1 {{__arm_agnostic("sme_za_state") is not supported together with __arm_new("za") or __arm_new("zt0")}} 106 __arm_new("zt0") void sme_arm_agnostic_arm_new_zt0(void) __arm_agnostic("sme_za_state") {} 107 108 // expected-cpp-error@+2 {{__arm_agnostic("sme_za_state") is not supported together with __arm_new("za") or __arm_new("zt0")}} 109 // expected-error@+1 {{__arm_agnostic("sme_za_state") is not supported together with __arm_new("za") or __arm_new("zt0")}} 110 __arm_new("za") void sme_arm_agnostic_arm_new_za(void) __arm_agnostic("sme_za_state") {} 111 112 // 113 // Check for incorrect conversions of function pointers with the attributes 114 // 115 116 typedef void (*n_ptrty) (void); 117 typedef void (*s_ptrty) (void) __arm_streaming; 118 s_ptrty return_valid_streaming_fptr(s_ptrty f) { return f; } 119 120 // expected-cpp-error@+2 {{cannot initialize return object of type 's_ptrty' (aka 'void (*)() __arm_streaming') with an lvalue of type 'n_ptrty' (aka 'void (*)()')}} 121 // expected-error@+1 {{incompatible function pointer types returning 'n_ptrty' (aka 'void (*)(void)') from a function with result type 's_ptrty' (aka 'void (*)(void) __arm_streaming')}} 122 s_ptrty return_invalid_fptr_streaming_normal(n_ptrty f) { return f; } 123 // expected-cpp-error@+2 {{cannot initialize return object of type 'n_ptrty' (aka 'void (*)()') with an lvalue of type 's_ptrty' (aka 'void (*)() __arm_streaming')}} 124 // expected-error@+1 {{incompatible function pointer types returning 's_ptrty' (aka 'void (*)(void) __arm_streaming') from a function with result type 'n_ptrty' (aka 'void (*)(void)')}} 125 n_ptrty return_invalid_fptr_normal_streaming(s_ptrty f) { return f; } 126 127 // Test an instance where the result type is not a prototyped function, such that we still get a diagnostic. 128 typedef void (*nonproto_n_ptrty) (); 129 // expected-cpp-error@+2 {{cannot initialize return object of type 'nonproto_n_ptrty' (aka 'void (*)()') with an lvalue of type 's_ptrty' (aka 'void (*)() __arm_streaming')}} 130 // expected-error@+1 {{incompatible function pointer types returning 's_ptrty' (aka 'void (*)(void) __arm_streaming') from a function with result type 'nonproto_n_ptrty' (aka 'void (*)()')}} 131 nonproto_n_ptrty return_invalid_fptr_streaming_nonprotonormal(s_ptrty f) { return f; } 132 133 typedef void (*sc_ptrty) (void) __arm_streaming_compatible; 134 sc_ptrty return_valid_streaming_compatible_fptr(sc_ptrty f) { return f; } 135 136 // expected-cpp-error@+2 {{cannot initialize return object of type 'sc_ptrty' (aka 'void (*)() __arm_streaming_compatible') with an lvalue of type 'n_ptrty' (aka 'void (*)()')}} 137 // expected-error@+1 {{incompatible function pointer types returning 'n_ptrty' (aka 'void (*)(void)') from a function with result type 'sc_ptrty' (aka 'void (*)(void) __arm_streaming_compatible')}} 138 sc_ptrty return_invalid_fptr_streaming_compatible_normal(n_ptrty f) { return f; } 139 // expected-cpp-error@+2 {{cannot initialize return object of type 'n_ptrty' (aka 'void (*)()') with an lvalue of type 'sc_ptrty' (aka 'void (*)() __arm_streaming_compatible')}} 140 // expected-error@+1 {{incompatible function pointer types returning 'sc_ptrty' (aka 'void (*)(void) __arm_streaming_compatible') from a function with result type 'n_ptrty' (aka 'void (*)(void)')}} 141 n_ptrty return_invalid_fptr_normal_streaming_compatible(sc_ptrty f) { return f; } 142 143 typedef void (*sz_ptrty) (void) __arm_inout("za"); 144 sz_ptrty return_valid_shared_za_fptr(sz_ptrty f) { return f; } 145 146 147 // expected-cpp-error@+2 {{cannot initialize return object of type 'sz_ptrty' (aka 'void (*)() __arm_inout("za")') with an lvalue of type 'n_ptrty' (aka 'void (*)()')}} 148 // expected-error@+1 {{incompatible function pointer types returning 'n_ptrty' (aka 'void (*)(void)') from a function with result type 'sz_ptrty' (aka 'void (*)(void) __arm_inout("za")')}} 149 sz_ptrty return_invalid_fptr_shared_za_normal(n_ptrty f) { return f; } 150 // expected-cpp-error@+2 {{cannot initialize return object of type 'n_ptrty' (aka 'void (*)()') with an lvalue of type 'sz_ptrty' (aka 'void (*)() __arm_inout("za")')}} 151 // expected-error@+1 {{incompatible function pointer types returning 'sz_ptrty' (aka 'void (*)(void) __arm_inout("za")') from a function with result type 'n_ptrty' (aka 'void (*)(void)')}} 152 n_ptrty return_invalid_fptr_normal_shared_za(sz_ptrty f) { return f; } 153 154 typedef void (*pz_ptrty) (void) __arm_preserves("za"); 155 pz_ptrty return_valid_preserves_za_fptr(pz_ptrty f) { return f; } 156 157 // expected-cpp-error@+2 {{cannot initialize return object of type 'pz_ptrty' (aka 'void (*)() __arm_preserves("za")') with an lvalue of type 'n_ptrty' (aka 'void (*)()')}} 158 // expected-error@+1 {{incompatible function pointer types returning 'n_ptrty' (aka 'void (*)(void)') from a function with result type 'pz_ptrty' (aka 'void (*)(void) __arm_preserves("za")')}} 159 pz_ptrty return_invalid_fptr_preserves_za_normal(n_ptrty f) { return f; } 160 // expected-cpp-error@+2 {{cannot initialize return object of type 'n_ptrty' (aka 'void (*)()') with an lvalue of type 'pz_ptrty' (aka 'void (*)() __arm_preserves("za")')}} 161 // expected-error@+1 {{incompatible function pointer types returning 'pz_ptrty' (aka 'void (*)(void) __arm_preserves("za")') from a function with result type 'n_ptrty' (aka 'void (*)(void)')}} 162 n_ptrty return_invalid_fptr_normal_preserves_za(pz_ptrty f) { return f; } 163 164 // Test template instantiations 165 #ifdef __cplusplus 166 template <typename T> T templated(T x) __arm_streaming { return x; } 167 template <> int templated<int>(int x) __arm_streaming { return x + 1; } 168 template <> float templated<float>(float x) __arm_streaming { return x + 2; } 169 // expected-cpp-error@+2 {{explicit instantiation of 'templated' does not refer to a function template, variable template, member function, member class, or static data member}} 170 // expected-cpp-note@-4 {{candidate template ignored: could not match 'short (short) __arm_streaming' against 'short (short)'}} 171 template short templated<short>(short); 172 #endif 173 174 // Conflicting attributes on redeclarations 175 176 // expected-error@+5 {{function declared 'void (void) __arm_streaming_compatible' was previously declared 'void (void) __arm_streaming', which has different SME function attributes}} 177 // expected-note@+3 {{previous declaration is here}} 178 // expected-cpp-error@+3 {{function declared 'void () __arm_streaming_compatible' was previously declared 'void () __arm_streaming', which has different SME function attributes}} 179 // expected-cpp-note@+1 {{previous declaration is here}} 180 void redecl(void) __arm_streaming; 181 void redecl(void) __arm_streaming_compatible { } 182 183 // expected-error@+5 {{function declared 'void (void)' was previously declared 'void (void) __arm_preserves("za")', which has different SME function attributes}} 184 // expected-note@+3 {{previous declaration is here}} 185 // expected-cpp-error@+3 {{function declared 'void ()' was previously declared 'void () __arm_preserves("za")', which has different SME function attributes}} 186 // expected-cpp-note@+1 {{previous declaration is here}} 187 void redecl_preserve_za(void) __arm_preserves("za");; 188 void redecl_preserve_za(void) {} 189 190 // expected-error@+5 {{function declared 'void (void) __arm_preserves("za")' was previously declared 'void (void)', which has different SME function attributes}} 191 // expected-note@+3 {{previous declaration is here}} 192 // expected-cpp-error@+3 {{function declared 'void () __arm_preserves("za")' was previously declared 'void ()', which has different SME function attributes}} 193 // expected-cpp-note@+1 {{previous declaration is here}} 194 void redecl_nopreserve_za(void); 195 void redecl_nopreserve_za(void) __arm_preserves("za") {} 196 197 void non_za_definition(void (*shared_za_fn_ptr)(void) __arm_inout("za"), void (*preserves_za_fn_ptr)(void) __arm_preserves("za")) { 198 sme_arm_new_za(); // OK 199 // expected-error@+2 {{call to a shared ZA function requires the caller to have ZA state}} 200 // expected-cpp-error@+1 {{call to a shared ZA function requires the caller to have ZA state}} 201 sme_arm_shared_za(); 202 // expected-error@+2 {{call to a shared ZA function requires the caller to have ZA state}} 203 // expected-cpp-error@+1 {{call to a shared ZA function requires the caller to have ZA state}} 204 shared_za_fn_ptr(); 205 // expected-error@+2 {{call to a shared ZA function requires the caller to have ZA state}} 206 // expected-cpp-error@+1 {{call to a shared ZA function requires the caller to have ZA state}} 207 preserves_za_fn_ptr(); 208 } 209 210 void shared_za_definition(void (*shared_za_fn_ptr)(void) __arm_inout("za")) __arm_inout("za") { 211 sme_arm_shared_za(); // OK 212 shared_za_fn_ptr(); // OK 213 } 214 215 __arm_new("za") void new_za_definition(void (*shared_za_fn_ptr)(void) __arm_inout("za")) { 216 sme_arm_shared_za(); // OK 217 shared_za_fn_ptr(); // OK 218 } 219 220 #ifdef __cplusplus 221 int shared_za_initializer(void) __arm_inout("za"); 222 // expected-cpp-error@+1 {{call to a shared ZA function requires the caller to have ZA state}} 223 int global = shared_za_initializer(); 224 225 struct S { 226 virtual void shared_za_memberfn(void) __arm_inout("za"); 227 }; 228 229 struct S2 : public S { 230 // expected-cpp-error@+2 {{virtual function 'shared_za_memberfn' has different attributes ('void ()') than the function it overrides (which has 'void () __arm_inout("za")')}} 231 // expected-cpp-note@-5 {{overridden virtual function is here}} 232 __arm_new("za") void shared_za_memberfn(void) override {} 233 }; 234 235 // The '__arm_preserves("za")' property cannot be dropped when overriding a virtual 236 // function. It is however fine for the overriding function to be '__arm_preserves("za")' 237 // even though the function that it overrides is not. 238 239 struct S_PreservesZA { 240 virtual void memberfn(void) __arm_preserves("za"); 241 }; 242 243 struct S_Drop_PreservesZA : S_PreservesZA { 244 // expected-cpp-error@+2 {{virtual function 'memberfn' has different attributes ('void ()') than the function it overrides (which has 'void () __arm_preserves("za")')}} 245 // expected-cpp-note@-5 {{overridden virtual function is here}} 246 void memberfn(void) override {} 247 }; 248 249 struct S_NoPreservesZA { 250 virtual void memberfn(void); 251 }; 252 253 struct S_AddPreservesZA : S_NoPreservesZA { 254 // expected-cpp-error@+2 {{virtual function 'memberfn' has different attributes ('void () __arm_preserves("za")') than the function it overrides (which has 'void ()')}} 255 // expected-cpp-note@-5 {{overridden virtual function is here}} 256 void memberfn(void) __arm_preserves("za") override {} 257 }; 258 259 260 // Check that the attribute propagates through template instantiations. 261 template <typename Ty> 262 struct S3 { 263 static constexpr int value = 0; 264 }; 265 266 template <> 267 struct S3<void (*)()> { 268 static constexpr int value = 1; 269 }; 270 271 template <> 272 struct S3<void (* __arm_streaming)()> { 273 static constexpr int value = 2; 274 }; 275 276 template <> 277 struct S3<void (* __arm_streaming_compatible)()> { 278 static constexpr int value = 4; 279 }; 280 281 template <> 282 struct S3<void (* __arm_inout("za"))()> { 283 static constexpr int value = 8; 284 }; 285 286 template <> 287 struct S3<void (* __arm_preserves("za"))()> { 288 static constexpr int value = 16; 289 }; 290 291 void normal_func(void) {} 292 void streaming_func(void) __arm_streaming {} 293 void streaming_compatible_func(void) __arm_streaming_compatible {} 294 void shared_za_func(void) __arm_inout("za") {} 295 void preserves_za_func(void) __arm_preserves("za") {} 296 297 static_assert(S3<decltype(+normal_func)>::value == 1, "why are we picking the wrong specialization?"); 298 static_assert(S3<decltype(+streaming_func)>::value == 2, "why are we picking the wrong specialization?"); 299 static_assert(S3<decltype(+streaming_compatible_func)>::value == 4, "why are we picking the wrong specialization?"); 300 static_assert(S3<decltype(+shared_za_func)>::value == 8, "why are we picking the wrong specialization?"); 301 static_assert(S3<decltype(+preserves_za_func)>::value == 16, "why are we picking the wrong specialization?"); 302 303 // Also test the attribute is propagated with variadic templates 304 constexpr int eval_variadic_template() { return 0; } 305 template <typename T, typename... Other> 306 constexpr int eval_variadic_template(T f, Other... other) { 307 return S3<decltype(f)>::value + eval_variadic_template(other...); 308 } 309 static_assert(eval_variadic_template(normal_func, streaming_func, 310 streaming_compatible_func, 311 shared_za_func, preserves_za_func) == 31, 312 "attributes not propagated properly in variadic template"); 313 314 // Test that the attribute is propagated with template specialization. 315 template<typename T> int test_templated_f(T); 316 template<> constexpr int test_templated_f<void(*)(void)>(void(*)(void)) { return 1; } 317 template<> constexpr int test_templated_f<void(*)(void)__arm_streaming>(void(*)(void)__arm_streaming) { return 2; } 318 template<> constexpr int test_templated_f<void(*)(void)__arm_streaming_compatible>(void(*)(void)__arm_streaming_compatible) { return 4; } 319 template<> constexpr int test_templated_f<void(*)(void)__arm_inout("za")>(void(*)(void)__arm_inout("za")) { return 8; } 320 template<> constexpr int test_templated_f<void(*)(void)__arm_preserves("za")>(void(*)(void)__arm_preserves("za")) { return 16; } 321 322 static_assert(test_templated_f(&normal_func) == 1, "Instantiated to wrong function"); 323 static_assert(test_templated_f(&streaming_func) == 2, "Instantiated to wrong function"); 324 static_assert(test_templated_f(&streaming_compatible_func) == 4, "Instantiated to wrong function"); 325 static_assert(test_templated_f(&shared_za_func) == 8, "Instantiated to wrong function"); 326 static_assert(test_templated_f(&preserves_za_func) == 16, "Instantiated to wrong function"); 327 328 // expected-cpp-error@+2 {{'__arm_streaming' only applies to function types; type here is 'int'}} 329 // expected-error@+1 {{'__arm_streaming' only applies to function types; type here is 'int'}} 330 int invalid_type_for_attribute __arm_streaming; 331 332 // Test overloads 333 constexpr int overload(void f(void)) { return 1; } 334 constexpr int overload(void f(void) __arm_streaming) { return 2; } 335 constexpr int overload(void f(void) __arm_streaming_compatible) { return 4; } 336 constexpr int overload(void f(void) __arm_inout("za")) { return 8; } 337 constexpr int overload(void f(void) __arm_preserves("za")) { return 16; } 338 static_assert(overload(&normal_func) == 1, "Overloaded to wrong function"); 339 static_assert(overload(&streaming_func) == 2, "Overloaded to wrong function"); 340 static_assert(overload(&streaming_compatible_func) == 4, "Overloaded to wrong function"); 341 static_assert(overload(&shared_za_func) == 8, "Overloaded to wrong function"); 342 static_assert(overload(&preserves_za_func) == 16, "Overloaded to wrong function"); 343 344 // Test implicit instantiation 345 template <typename T> struct X { 346 static void foo(T) __arm_streaming { } 347 }; 348 constexpr int overload_int(void f(int)) { return 1; } 349 constexpr int overload_int(void f(int) __arm_streaming) { return 2; } 350 constexpr X<int> *ptr = 0; 351 static_assert(overload_int(ptr->foo) == 2, "Overloaded to the wrong function after implicit instantiation"); 352 353 #endif // ifdef __cplusplus 354 355 // expected-cpp-error@+2 {{unknown state ''}} 356 // expected-error@+1 {{unknown state ''}} 357 __arm_new("") void invalid_arm_new_empty_string(void); 358 // expected-cpp-error@+2 {{expected string literal as argument of '__arm_new' attribute}} 359 // expected-error@+1 {{expected string literal as argument of '__arm_new' attribute}} 360 __arm_new(0) void invalid_arm_new_non_literal_string(void); 361 // expected-cpp-error@+2 {{unknown state 'unknownstate'}} 362 // expected-error@+1 {{unknown state 'unknownstate'}} 363 __arm_new("unknownstate") void invalid_arm_new_unknown_state(void); 364 365 // expected-cpp-error@+2 {{unknown state ''}} 366 // expected-error@+1 {{unknown state ''}} 367 void invalid_arm_in_empty_string(void) __arm_in(""); 368 // expected-cpp-error@+2 {{expected string literal as argument of '__arm_in' attribute}} 369 // expected-error@+1 {{expected string literal as argument of '__arm_in' attribute}} 370 void invalid_arm_in_non_literal_string(void) __arm_in(0); 371 // expected-cpp-error@+2 {{unknown state 'unknownstate'}} 372 // expected-error@+1 {{unknown state 'unknownstate'}} 373 void invalid_arm_in_unknown_state(void) __arm_in("unknownstate"); 374 375 void valid_state_attrs_in_in1(void) __arm_in("za"); 376 void valid_state_attrs_in_in2(void) __arm_in("za", "za"); 377 void valid_state_attrs_in_in3(void) __arm_in("zt0"); 378 void valid_state_attrs_in_in4(void) __arm_in("zt0", "zt0"); 379 void valid_state_attrs_in_in5(void) __arm_in("za", "zt0"); 380 __arm_new("za") void valid_state_attrs_in_in6(void) __arm_in("zt0"); 381 __arm_new("zt0") void valid_state_attrs_in_in7(void) __arm_in("za"); 382 383 // expected-cpp-error@+2 {{missing state for '__arm_in'}} 384 // expected-error@+1 {{missing state for '__arm_in'}} 385 void invalid_state_attrs_no_arg1(void) __arm_in(); 386 // expected-cpp-error@+2 {{missing state for '__arm_new'}} 387 // expected-error@+1 {{missing state for '__arm_new'}} 388 __arm_new() void invalid_state_attrs_no_arg2(void); 389 390 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}} 391 // expected-error@+1 {{conflicting attributes for state 'za'}} 392 void conflicting_state_attrs_in_out(void) __arm_in("za") __arm_out("za"); 393 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}} 394 // expected-error@+1 {{conflicting attributes for state 'za'}} 395 void conflicting_state_attrs_in_inout(void) __arm_in("za") __arm_inout("za"); 396 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}} 397 // expected-error@+1 {{conflicting attributes for state 'za'}} 398 void conflicting_state_attrs_in_preserves(void) __arm_in("za") __arm_preserves("za"); 399 400 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}} 401 // expected-error@+1 {{conflicting attributes for state 'za'}} 402 void conflicting_state_attrs_out_in(void) __arm_out("za") __arm_in("za"); 403 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}} 404 // expected-error@+1 {{conflicting attributes for state 'za'}} 405 void conflicting_state_attrs_out_inout(void) __arm_out("za") __arm_inout("za"); 406 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}} 407 // expected-error@+1 {{conflicting attributes for state 'za'}} 408 void conflicting_state_attrs_out_preserves(void) __arm_out("za") __arm_preserves("za"); 409 410 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}} 411 // expected-error@+1 {{conflicting attributes for state 'za'}} 412 void conflicting_state_attrs_inout_in(void) __arm_inout("za") __arm_in("za"); 413 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}} 414 // expected-error@+1 {{conflicting attributes for state 'za'}} 415 void conflicting_state_attrs_inout_out(void) __arm_inout("za") __arm_out("za"); 416 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}} 417 // expected-error@+1 {{conflicting attributes for state 'za'}} 418 void conflicting_state_attrs_inout_preserves(void) __arm_inout("za") __arm_preserves("za"); 419 420 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}} 421 // expected-error@+1 {{conflicting attributes for state 'za'}} 422 void conflicting_state_attrs_preserves_in(void) __arm_preserves("za") __arm_in("za"); 423 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}} 424 // expected-error@+1 {{conflicting attributes for state 'za'}} 425 void conflicting_state_attrs_preserves_out(void) __arm_preserves("za") __arm_out("za"); 426 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}} 427 // expected-error@+1 {{conflicting attributes for state 'za'}} 428 void conflicting_state_attrs_preserves_inout(void) __arm_preserves("za") __arm_inout("za"); 429 430 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}} 431 // expected-error@+1 {{conflicting attributes for state 'zt0'}} 432 void conflicting_state_attrs_in_out_zt0(void) __arm_in("zt0") __arm_out("zt0"); 433 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}} 434 // expected-error@+1 {{conflicting attributes for state 'zt0'}} 435 void conflicting_state_attrs_in_inout_zt0(void) __arm_in("zt0") __arm_inout("zt0"); 436 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}} 437 // expected-error@+1 {{conflicting attributes for state 'zt0'}} 438 void conflicting_state_attrs_in_preserves_zt0(void) __arm_in("zt0") __arm_preserves("zt0"); 439 440 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}} 441 // expected-error@+1 {{conflicting attributes for state 'zt0'}} 442 void conflicting_state_attrs_out_in_zt0(void) __arm_out("zt0") __arm_in("zt0"); 443 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}} 444 // expected-error@+1 {{conflicting attributes for state 'zt0'}} 445 void conflicting_state_attrs_out_inout_zt0(void) __arm_out("zt0") __arm_inout("zt0"); 446 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}} 447 // expected-error@+1 {{conflicting attributes for state 'zt0'}} 448 void conflicting_state_attrs_out_preserves_zt0(void) __arm_out("zt0") __arm_preserves("zt0"); 449 450 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}} 451 // expected-error@+1 {{conflicting attributes for state 'zt0'}} 452 void conflicting_state_attrs_inout_in_zt0(void) __arm_inout("zt0") __arm_in("zt0"); 453 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}} 454 // expected-error@+1 {{conflicting attributes for state 'zt0'}} 455 void conflicting_state_attrs_inout_out_zt0(void) __arm_inout("zt0") __arm_out("zt0"); 456 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}} 457 // expected-error@+1 {{conflicting attributes for state 'zt0'}} 458 void conflicting_state_attrs_inout_preserves_zt0(void) __arm_inout("zt0") __arm_preserves("zt0"); 459 460 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}} 461 // expected-error@+1 {{conflicting attributes for state 'zt0'}} 462 void conflicting_state_attrs_preserves_in_zt0(void) __arm_preserves("zt0") __arm_in("zt0"); 463 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}} 464 // expected-error@+1 {{conflicting attributes for state 'zt0'}} 465 void conflicting_state_attrs_preserves_out_zt0(void) __arm_preserves("zt0") __arm_out("zt0"); 466 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}} 467 // expected-error@+1 {{conflicting attributes for state 'zt0'}} 468 void conflicting_state_attrs_preserves_inout_zt0(void) __arm_preserves("zt0") __arm_inout("zt0"); 469 470 // Test that we get a diagnostic for unimplemented case. 471 void unimplemented_spill_fill_za(void (*share_zt0_only)(void) __arm_inout("zt0")) __arm_inout("za", "zt0") { 472 // expected-cpp-error@+4 {{call to a function that shares state other than 'za' from a function that has live 'za' state requires a spill/fill of ZA, which is not yet implemented}} 473 // expected-cpp-note@+3 {{add '__arm_preserves("za")' to the callee if it preserves ZA}} 474 // expected-error@+2 {{call to a function that shares state other than 'za' from a function that has live 'za' state requires a spill/fill of ZA, which is not yet implemented}} 475 // expected-note@+1 {{add '__arm_preserves("za")' to the callee if it preserves ZA}} 476 share_zt0_only(); 477 } 478 479 void sme_streaming_with_vl_arg(__SVInt8_t a) __arm_streaming { } 480 481 __SVInt8_t sme_streaming_returns_vl(void) __arm_streaming { __SVInt8_t r; return r; } 482 483 void sme_streaming_compatible_with_vl_arg(__SVInt8_t a) __arm_streaming_compatible { } 484 485 __SVInt8_t sme_streaming_compatible_returns_vl(void) __arm_streaming_compatible { __SVInt8_t r; return r; } 486 487 void sme_no_streaming_with_vl_arg(__SVInt8_t a) { } 488 489 __SVInt8_t sme_no_streaming_returns_vl(void) { __SVInt8_t r; return r; } 490 491 // expected-warning@+2 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 492 // expected-cpp-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 493 __arm_locally_streaming void sme_locally_streaming_with_vl_arg(__SVInt8_t a) { } 494 495 // expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 496 // expected-cpp-warning@+1 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 497 __arm_locally_streaming __SVInt8_t sme_locally_streaming_returns_vl(void) { __SVInt8_t r; return r; } 498 499 void sme_no_streaming_calling_streaming_with_vl_args() { 500 __SVInt8_t a; 501 // expected-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 502 // expected-cpp-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 503 sme_streaming_with_vl_arg(a); 504 } 505 506 void sme_no_streaming_calling_streaming_with_return_vl() { 507 // expected-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 508 // expected-cpp-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 509 __SVInt8_t r = sme_streaming_returns_vl(); 510 } 511 512 void sme_streaming_calling_non_streaming_with_vl_args(void) __arm_streaming { 513 __SVInt8_t a; 514 // expected-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 515 // expected-cpp-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 516 sme_no_streaming_with_vl_arg(a); 517 } 518 519 void sme_streaming_calling_non_streaming_with_return_vl(void) __arm_streaming { 520 // expected-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 521 // expected-cpp-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 522 __SVInt8_t r = sme_no_streaming_returns_vl(); 523 } 524 525 void sme_no_streaming_calling_streaming_with_vl_args_param(__SVInt8_t arg, void (*sc)( __SVInt8_t arg) __arm_streaming) { 526 // expected-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 527 // expected-cpp-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 528 sc(arg); 529 } 530 531 __SVInt8_t sme_no_streaming_calling_streaming_return_vl_param(__SVInt8_t (*s)(void) __arm_streaming) { 532 // expected-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 533 // expected-cpp-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 534 return s(); 535 } 536 537 void sme_streaming_compatible_calling_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { 538 // expected-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 539 // expected-cpp-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 540 sme_streaming_with_vl_arg(arg); 541 } 542 543 void sme_streaming_compatible_calling_sme_streaming_return_vl(void) __arm_streaming_compatible { 544 // expected-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 545 // expected-cpp-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 546 __SVInt8_t r = sme_streaming_returns_vl(); 547 } 548 549 void sme_streaming_compatible_calling_no_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { 550 // expected-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 551 // expected-cpp-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 552 sme_no_streaming_with_vl_arg(arg); 553 } 554 555 void sme_streaming_compatible_calling_no_sme_streaming_return_vl(void) __arm_streaming_compatible { 556 // expected-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 557 // expected-cpp-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} 558 __SVInt8_t r = sme_no_streaming_returns_vl(); 559 } 560 561 void sme_streaming_calling_streaming(__SVInt8_t arg, void (*s)( __SVInt8_t arg) __arm_streaming) __arm_streaming { 562 s(arg); 563 } 564 565 __SVInt8_t sme_streaming_calling_streaming_return_vl(__SVInt8_t (*s)(void) __arm_streaming) __arm_streaming { 566 return s(); 567 } 568 569 void sme_streaming_calling_streaming_with_vl_args(__SVInt8_t a) __arm_streaming { 570 sme_streaming_with_vl_arg(a); 571 } 572 573 void sme_streaming_calling_streaming_with_return_vl(void) __arm_streaming { 574 __SVInt8_t r = sme_streaming_returns_vl(); 575 } 576 577 void sme_streaming_calling_streaming_compatible_with_vl_args(__SVInt8_t a) __arm_streaming { 578 sme_streaming_compatible_with_vl_arg(a); 579 } 580 581 void sme_streaming_calling_streaming_compatible_with_return_vl(void) __arm_streaming { 582 __SVInt8_t r = sme_streaming_compatible_returns_vl(); 583 } 584 585 void sme_no_streaming_calling_streaming_compatible_with_vl_args() { 586 __SVInt8_t a; 587 sme_streaming_compatible_with_vl_arg(a); 588 } 589 590 void sme_no_streaming_calling_streaming_compatible_with_return_vl() { 591 __SVInt8_t r = sme_streaming_compatible_returns_vl(); 592 } 593 594 void sme_no_streaming_calling_non_streaming_compatible_with_vl_args() { 595 __SVInt8_t a; 596 sme_no_streaming_with_vl_arg(a); 597 } 598 599 void sme_no_streaming_calling_non_streaming_compatible_with_return_vl() { 600 __SVInt8_t r = sme_no_streaming_returns_vl(); 601 } 602 603 void sme_streaming_compatible_calling_streaming_compatible_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { 604 sme_streaming_compatible_with_vl_arg(arg); 605 } 606 607 void sme_streaming_compatible_calling_streaming_compatible_with_return_vl(void) __arm_streaming_compatible { 608 __SVInt8_t r = sme_streaming_compatible_returns_vl(); 609 } 610