https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122483

--- Comment #17 from H.J. Lu <hjl.tools at gmail dot com> ---
(In reply to Richard Sandiford from comment #16)
> (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.

For x86, I got

[hjl@gnu-tgl-3 gcc]$ cat x.c 
extern void bar(void);
void (*foo)(void) __attribute__ ((preserve_none)) = bar;
[hjl@gnu-tgl-3 gcc]$ ./xgcc -B./ -S -O2 x.c 
x.c:2:53: error: initialization of ‘void (__attribute__((preserve_none))
*)(void)’ from incompatible pointer type ‘void (*)(void)’
[-Wincompatible-pointer-types]
    2 | void (*foo)(void) __attribute__ ((preserve_none)) = bar;
      |                                                     ^~~
x.c:1:13: note: ‘bar’ declared here
    1 | extern void bar(void);
      |             ^~~
[hjl@gnu-tgl-3 gcc]$ 

since ix86_comp_type_attributes returns 0:

  if (ix86_type_no_callee_saved_registers_p (type1)
      != ix86_type_no_callee_saved_registers_p (type2))
    return 0;

Does aarch64_comp_type_attributes check [[arm::streaming_compatible]]?

Reply via email to