https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122483
Richard Sandiford <rsandifo at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |rsandifo at gcc dot gnu.org
--- Comment #16 from Richard Sandiford <rsandifo at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #14)
> I think diagnosing
>
> void sc_b ();
> void sc_b () [[arm::streaming_compatible]]; // { dg-error "conflicting
> types" }
>
> which still works is good. Diagnosing
>
> void sc_a () [[arm::streaming_compatible]];
> void sc_a (); // { dg-error "conflicting types" }
>
> which no longer works is not necessary - the latter declaration does not
> actually remove the attribute, so the type of sc_a isn't changed and all
> possible users of sc_a see the attributed declaration.
>
> So IMO this works as expected and in the appropriate way.
>
> Thus, a testsuite issue, the tests should be fixed.
I disagree. Like Alex says in comment 11 and comment 12,
[[arm::streaming_compatible]] is a type attribute rather than a declaration
attribute and it changes the ABI of the function. A type without
[[arm::streaming_compatible]] is as different from a type with
[[arm::streaming_compatible]] as a type that returns "int"s is different from a
type that returns structures.
Code like:
void bar(void);
void (*foo)(void) [[arm::streaming_compatible]] = bar;
is a hard error [https://godbolt.org/z/b7GTo6nPx], so it doesn't IMO make sense
for:
void bar(void);
to be treated as a redeclaration of:
void bar(void) [[arm::streaming_compatible]];
any more than:
int bar(void);
can be a redeclaration of:
void bar(void);
It also seems odd that:
extern void bar(void) [[arm::streaming_compatible]];
extern void bar(void);
is ok but:
extern void (*foo)(void) [[arm::streaming_compatible]];
extern void (*foo)(void);
is not [https://godbolt.org/z/E6hevqvs6].
I think we need a way to distinguish the two cases (the one that HJ wants and
the one that ACLE wants). As it stands, the P1 seems appropriate.