aarch64, testsuite: Extend SME attribute tests [PR122483]

Message ID adZC-AeasauTTf_U@arm.com
State New
Delegated to: Tamar Christina
Headers
Series aarch64, testsuite: Extend SME attribute tests [PR122483] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed

Commit Message

Alex Coplan April 8, 2026, 11:58 a.m. UTC
  This is a follow-up patch which depends on the fixes for PR122483:
https://patchwork.sourceware.org/project/gcc/list/?series=59377

This extends the SME attribute tests (streaming_mode_1.c and
za_state_1.c) with cases that involve one or both of the duplicate decls
having extraneous non-type-affecting attributes, to verify that this
doesn't affect the rejection of cases that would otherwise be rejected
due to incompatible SME attributes.

The aim is to address Joseph's review comment on the C frontend patch in
the series that fixes PR122483:

> > The motivation is to restore the rejection of code such as:
> >
> >   void f(void) [[arm::streaming]];
> >   void f(void);
>
> What happens, and what is supposed to happen, when one or both
> declarations have function type attributes that aren't meant to prevent
> merging, in addition to the ones that are meant to prevent merging?  (Such
> as unsequenced / reproducible / gnu::format / ....)

(https://inbox.sourceware.org/gcc-patches/91332677-b0d8-d097-151d-3690ff42c897@redhat.com/)

I've verified that the tests still pass on aarch64-linux-gnu on top of
the other patches in the series.  OK for trunk once the dependent
patches (all except the C++ patch) have been approved and committed?

Thanks,
Alex

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/sme/streaming_mode_1.c: Add variants with
	extraneous non-conflicting attributes.
	* gcc.target/aarch64/sme/za_state_1.c: Likewise.
  

Patch

diff --git a/gcc/testsuite/gcc.target/aarch64/sme/streaming_mode_1.c b/gcc/testsuite/gcc.target/aarch64/sme/streaming_mode_1.c
index cb1b05948d8..bdd0839df65 100644
--- a/gcc/testsuite/gcc.target/aarch64/sme/streaming_mode_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sme/streaming_mode_1.c
@@ -3,12 +3,64 @@ 
 void sc_a () [[arm::streaming_compatible]];
 void sc_a (); // { dg-error "conflicting types" }
 
+// Variants of sc_a, checking that the presence of extraneous
+// compatible attributes doesn't affect the rejection.
+
+int sc_a1 (int) [[arm::streaming_compatible, unsequenced]];
+int sc_a1 (int); // { dg-error "conflicting types" }
+
+int sc_a2 (int) [[unsequenced, arm::streaming_compatible]];
+int sc_a2 (int); // { dg-error "conflicting types" }
+
+int sc_a3 (int) [[arm::streaming_compatible]];
+int sc_a3 (int) [[unsequenced]]; // { dg-error "conflicting types" }
+
+int sc_a4 (int) [[arm::streaming_compatible, unsequenced]];
+int sc_a4 (int) [[unsequenced]]; // { dg-error "conflicting types" }
+
+int sc_a5 (int) [[unsequenced, arm::streaming_compatible]];
+int sc_a5 (int) [[unsequenced]]; // { dg-error "conflicting types" }
+
 void sc_b ();
 void sc_b () [[arm::streaming_compatible]]; // { dg-error "conflicting types" }
 
+// Likewise with sc_b.
+
+int sc_b1 (int) [[reproducible]];
+int sc_b1 (int) [[arm::streaming_compatible]]; // { dg-error "conflicting types" }
+
+int sc_b2 (int);
+int sc_b2 (int) [[arm::streaming_compatible, reproducible]]; // { dg-error "conflicting types" }
+
+int sc_b3 (int);
+int sc_b3 (int) [[reproducible, arm::streaming_compatible]]; // { dg-error "conflicting types" }
+
+int sc_b4 (int) [[reproducible]];
+int sc_b4 (int) [[arm::streaming_compatible, reproducible]]; // { dg-error "conflicting types" }
+
+int sc_b5 (int) [[reproducible]];
+int sc_b5 (int) [[reproducible, arm::streaming_compatible]]; // { dg-error "conflicting types" }
+
 void sc_c () [[arm::streaming_compatible]];
 void sc_c () {} // { dg-error "conflicting types" }
 
+// Likewise with sc_c.
+
+int sc_c1 (int) [[arm::streaming_compatible, unsequenced]];
+int sc_c1 (int) {} // { dg-error "conflicting types" }
+
+int sc_c2 (int) [[unsequenced, arm::streaming_compatible]];
+int sc_c2 (int) {} // { dg-error "conflicting types" }
+
+int sc_c3 (int) [[arm::streaming_compatible]];
+int sc_c3 (int) [[unsequenced]] {} // { dg-error "conflicting types" }
+
+int sc_c4 (int) [[arm::streaming_compatible, unsequenced]];
+int sc_c4 (int) [[unsequenced]] {} // { dg-error "conflicting types" }
+
+int sc_c5 (int) [[unsequenced, arm::streaming_compatible]];
+int sc_c5 (int) [[unsequenced]] {} // { dg-error "conflicting types" }
+
 void sc_d ();
 void sc_d () [[arm::streaming_compatible]] {} // { dg-error "conflicting types" }
 
@@ -29,15 +81,84 @@  extern void (*sc_h) (); // { dg-error "conflicting types" }
 void s_a () [[arm::streaming]];
 void s_a (); // { dg-error "conflicting types" }
 
+// Variants of s_a, checking that the presence of extraneous
+// compatible attributes doesn't affect the rejection.
+
+int s_a1 () [[arm::streaming, gnu::warn_unused_result]];
+int s_a1 (); // { dg-error "conflicting types" }
+
+int s_a2 () [[gnu::warn_unused_result, arm::streaming]];
+int s_a2 (); // { dg-error "conflicting types" }
+
+int s_a3 () [[arm::streaming]];
+int s_a3 () [[gnu::warn_unused_result]]; // { dg-error "conflicting types" }
+
+int s_a4 () [[arm::streaming, gnu::warn_unused_result]];
+int s_a4 () [[gnu::warn_unused_result]]; // { dg-error "conflicting types" }
+
+int s_a5 () [[gnu::warn_unused_result, arm::streaming]];
+int s_a5 () [[gnu::warn_unused_result]]; // { dg-error "conflicting types" }
+
 void s_b ();
 void s_b () [[arm::streaming]]; // { dg-error "conflicting types" }
 
+// Likewise with s_b.
+
+int s_b1 (int) [[unsequenced]];
+int s_b1 (int) [[arm::streaming]]; // { dg-error "conflicting types" }
+
+int s_b2 (int);
+int s_b2 (int) [[arm::streaming, unsequenced]]; // { dg-error "conflicting types" }
+
+int s_b3 (int);
+int s_b3 (int) [[unsequenced, arm::streaming]]; // { dg-error "conflicting types" }
+
+int s_b4 (int) [[unsequenced]];
+int s_b4 (int) [[arm::streaming, unsequenced]]; // { dg-error "conflicting types" }
+
+int s_b5 (int) [[unsequenced]];
+int s_b5 (int) [[unsequenced, arm::streaming]]; // { dg-error "conflicting types" }
+
 void s_c () [[arm::streaming]];
 void s_c () {} // { dg-error "conflicting types" }
 
+// Likewise with s_c.
+
+int s_c1 (int) [[arm::streaming, reproducible]];
+int s_c1 (int) {} // { dg-error "conflicting types" }
+
+int s_c2 (int) [[reproducible, arm::streaming]];
+int s_c2 (int) {} // { dg-error "conflicting types" }
+
+int s_c3 (int) [[arm::streaming]];
+int s_c3 (int) [[reproducible]] {} // { dg-error "conflicting types" }
+
+int s_c4 (int) [[arm::streaming, reproducible]];
+int s_c4 (int) [[reproducible]] {} // { dg-error "conflicting types" }
+
+int s_c5 (int) [[reproducible, arm::streaming]];
+int s_c5 (int) [[reproducible]] {} // { dg-error "conflicting types" }
+
 void s_d ();
 void s_d () [[arm::streaming]] {} // { dg-error "conflicting types" }
 
+// Likewise with s_d.
+
+int s_d1 () [[gnu::warn_unused_result]];
+int s_d1 () [[arm::streaming]] {} // { dg-error "conflicting types" }
+
+int s_d2 ();
+int s_d2 () [[gnu::warn_unused_result, arm::streaming]] {} // { dg-error "conflicting types" }
+
+int s_d3 ();
+int s_d3 () [[arm::streaming, gnu::warn_unused_result]] {} // { dg-error "conflicting types" }
+
+int s_d4 () [[gnu::warn_unused_result]];
+int s_d4 () [[arm::streaming, gnu::warn_unused_result]] {} // { dg-error "conflicting types" }
+
+int s_d4 () [[gnu::warn_unused_result]];
+int s_d4 () [[gnu::warn_unused_result, arm::streaming]] {} // { dg-error "conflicting types" }
+
 void s_e () [[arm::streaming]] {}
 void s_e (); // { dg-error "conflicting types" }
 
@@ -55,9 +176,51 @@  extern void (*s_h) (); // { dg-error "conflicting types" }
 void mixed_a () [[arm::streaming]];
 void mixed_a () [[arm::streaming_compatible]]; // { dg-error "conflicting types" }
 
+// Variants of mixed_a, checking that the presence of extraneous
+// compatible attributes doesn't affect the rejection.
+
+int mixed_a1 (int) [[arm::streaming, unsequenced]];
+int mixed_a1 (int) [[arm::streaming_compatible]]; // { dg-error "conflicting types" }
+
+int mixed_a2 (int) [[unsequenced, arm::streaming]];
+int mixed_a2 (int) [[arm::streaming_compatible]]; // { dg-error "conflicting types" }
+
+int mixed_a3 (int) [[arm::streaming]];
+int mixed_a3 (int) [[arm::streaming_compatible, unsequenced]]; // { dg-error "conflicting types" }
+
+int mixed_a4 (int) [[arm::streaming]];
+int mixed_a4 (int) [[unsequenced, arm::streaming_compatible]]; // { dg-error "conflicting types" }
+
+int mixed_a5 (int) [[arm::streaming, unsequenced]];
+int mixed_a5 (int) [[arm::streaming_compatible, unsequenced]]; // { dg-error "conflicting types" }
+
+int mixed_a6 (int) [[unsequenced, arm::streaming]];
+int mixed_a6 (int) [[arm::streaming_compatible, unsequenced]]; // { dg-error "conflicting types" }
+
+int mixed_a7 (int) [[arm::streaming, unsequenced]];
+int mixed_a7 (int) [[unsequenced, arm::streaming_compatible]]; // { dg-error "conflicting types" }
+
+int mixed_a8 (int) [[unsequenced, arm::streaming]];
+int mixed_a8 (int) [[unsequenced, arm::streaming_compatible]]; // { dg-error "conflicting types" }
+
 void mixed_b () [[arm::streaming_compatible]];
 void mixed_b () [[arm::streaming]]; // { dg-error "conflicting types" }
 
+// Likewise with variants of mixed_b (although not including all
+// permutations).
+
+int mixed_b1 (int) [[arm::streaming_compatible]];
+int mixed_b1 (int) [[arm::streaming]]; // { dg-error "conflicting types" }
+
+int mixed_b2 (int) [[arm::streaming_compatible, reproducible]];
+int mixed_b2 (int) [[arm::streaming]]; // { dg-error "conflicting types" }
+
+int mixed_b3 (int) [[arm::streaming_compatible]];
+int mixed_b3 (int) [[arm::streaming, reproducible]]; // { dg-error "conflicting types" }
+
+int mixed_b4 (int) [[arm::streaming_compatible, reproducible]];
+int mixed_b4 (int) [[arm::streaming, reproducible]]; // { dg-error "conflicting types" }
+
 void mixed_c () [[arm::streaming]];
 void mixed_c () [[arm::streaming_compatible]] {} // { dg-error "conflicting types" }
 
@@ -120,9 +283,44 @@  void keyword_ok_5 () [[arm::streaming_compatible]];
 void keyword_contradiction_1 () __arm_streaming;
 void keyword_contradiction_1 (); // { dg-error "conflicting types" }
 
+// Variants of keyword_contradiction_1, checking that the presence of
+// extraneous compatible attributes doesn't affect the rejection.
+
+int keyword_contradiction_1a (int) __arm_streaming [[unsequenced]];
+int keyword_contradiction_1a (int); // { dg-error "conflicting types" }
+
+int keyword_contradiction_1b (int) [[unsequenced]] __arm_streaming;
+int keyword_contradiction_1b (int); // { dg-error "conflicting types" }
+
+int keyword_contradiction_1c (int) __arm_streaming;
+int keyword_contradiction_1c (int) [[unsequenced]]; // { dg-error "conflicting types" }
+
+int keyword_contradiction_1d (int) __arm_streaming [[unsequenced]];
+int keyword_contradiction_1d (int) [[unsequenced]]; // { dg-error "conflicting types" }
+
+int keyword_contradiction_1e (int) [[unsequenced]] __arm_streaming;
+int keyword_contradiction_1e (int) [[unsequenced]]; // { dg-error "conflicting types" }
+
 void keyword_contradiction_2 ();
 void keyword_contradiction_2 () __arm_streaming; // { dg-error "conflicting types" }
 
+// Likewise with keyword_contradiction_2.
+
+int keyword_contradiction_2a (int) [[reproducible]];
+int keyword_contradiction_2a (int) __arm_streaming; // { dg-error "conflicting types" }
+
+int keyword_contradiction_2b (int);
+int keyword_contradiction_2b (int) __arm_streaming [[reproducible]]; // { dg-error "conflicting types" }
+
+int keyword_contradiction_2c (int);
+int keyword_contradiction_2c (int) [[reproducible]] __arm_streaming ; // { dg-error "conflicting types" }
+
+int keyword_contradiction_2d (int) [[reproducible]];
+int keyword_contradiction_2d (int) __arm_streaming [[reproducible]]; // { dg-error "conflicting types" }
+
+int keyword_contradiction_2e (int) [[reproducible]];
+int keyword_contradiction_2e (int) [[reproducible]] __arm_streaming ; // { dg-error "conflicting types" }
+
 void keyword_contradiction_3 () __arm_streaming;
 void keyword_contradiction_3 () [[arm::streaming_compatible]]; // { dg-error "conflicting types" }
 
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/za_state_1.c b/gcc/testsuite/gcc.target/aarch64/sme/za_state_1.c
index 7d7989b18b3..012b143b200 100644
--- a/gcc/testsuite/gcc.target/aarch64/sme/za_state_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sme/za_state_1.c
@@ -3,9 +3,44 @@ 
 void shared_a () [[arm::inout("za")]];
 void shared_a (); // { dg-error "conflicting types" }
 
+// Variants of shared_a, checking that the presence of extraneous
+// compatible attributes doesn't affect the rejection.
+
+int shared_a1 (int) [[arm::inout("za"), unsequenced]];
+int shared_a1 (int); // { dg-error "conflicting types" }
+
+int shared_a2 (int) [[unsequenced, arm::inout("za")]];
+int shared_a2 (int); // { dg-error "conflicting types" }
+
+int shared_a3 (int) [[arm::inout("za")]];
+int shared_a3 (int) [[unsequenced]]; // { dg-error "conflicting types" }
+
+int shared_a4 (int) [[arm::inout("za"), unsequenced]];
+int shared_a4 (int) [[unsequenced]]; // { dg-error "conflicting types" }
+
+int shared_a5 (int) [[unsequenced, arm::inout("za")]];
+int shared_a5 (int) [[unsequenced]]; // { dg-error "conflicting types" }
+
 void shared_b ();
 void shared_b () [[arm::inout("za")]]; // { dg-error "conflicting types" }
 
+// Likewise with shared_b.
+
+int shared_b1 () [[gnu::warn_unused_result]];
+int shared_b1 () [[arm::inout("za")]]; // { dg-error "conflicting types" }
+
+int shared_b2 ();
+int shared_b2 () [[arm::inout("za"), gnu::warn_unused_result]]; // { dg-error "conflicting types" }
+
+int shared_b3 ();
+int shared_b3 () [[gnu::warn_unused_result, arm::inout("za")]]; // { dg-error "conflicting types" }
+
+int shared_b4 () [[gnu::warn_unused_result]];
+int shared_b4 () [[arm::inout("za"), gnu::warn_unused_result]]; // { dg-error "conflicting types" }
+
+int shared_b5 () [[gnu::warn_unused_result]];
+int shared_b5 () [[gnu::warn_unused_result, arm::inout("za")]]; // { dg-error "conflicting types" }
+
 void shared_c () [[arm::inout("za")]];
 void shared_c () {} // { dg-error "conflicting types" }