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

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

C++ has been always behaving this way:

[hjl@gnu-tgl-3 gcc]$ cat x.c 
extern void foo(void) __attribute__ ((ms_abi));
extern void foo(void);
[hjl@gnu-tgl-3 gcc]$ /usr/gcc-14.2.1-x32/bin/c++ -S -O2 x.c
[hjl@gnu-tgl-3 gcc]$

Reply via email to