Bug 87592 - overriding attribute constructor and destructor priority not diagnosed
Summary: overriding attribute constructor and destructor priority not diagnosed
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2018-10-11 19:51 UTC by Martin Sebor
Modified: 2018-10-11 20:01 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2018-10-11 19:51:23 UTC
Here's an example of another inconsistency in GCC's handling of attributes -- even though it implicates another attribute this bug is specifically about attribute constructor and destructor.

When the aligned attribute is specified with different arguments on distinct declarations of the same variable, the most restrictive one wins.  (This matches the C11 requirement on the _Alignas attribute and what other compilers do, although it isn't documented for attribute aligned in the manual.)

In contrast, when the format_arg attribute is specified with different arguments on distinct declarations of the same function they are all (counter-inuitively) accepted.  Clang accepts just the last one.

But when the constructor attribute is specified with different arguments on distinct declarations of the same function, the first one wins and the subsequent ones are ignored, again with no warning.  This is not only different from either of the two cases above but also from what Clang does: it accepts the attribute on the definition of the function.  I'd say the Clang behavior makes more sense here because the attribute matters for definitions of the function, not for declarations.

$ cat y.c && /ssd/build/gcc-81824/gcc/xgcc -B /ssd/build/gcc-81824/gcc -Wall y.c && ./a.out
__attribute__ ((aligned (8))) char i;
__attribute__ ((aligned (16))) char i;
__attribute__ ((aligned (4))) char i;

__attribute__ ((constructor (103))) void f103 (void)
{ __builtin_puts (__func__); }

__attribute__ ((constructor (105))) void f105 (void)
{ __builtin_puts (__func__); }

__attribute__ ((constructor (106))) void f10x (void);   // accepted
__attribute__ ((constructor (104))) void f10x (void)    // ignored
{ __builtin_puts (__func__); }

__attribute__ ((format_arg (2))) char* g (char*, char*);      // accepted
__attribute__ ((format_arg (1))) char* g (char *s, char *t)   // accepted
{ return t; }

void h (void)
{
  __builtin_printf (g ("%i", "%s"), 123);     // -Wformat
  __builtin_printf (g ("%i", "%s"), "abc");   // also -Wformat
}

int main (void)
{
  __builtin_printf ("alignof (i) = %zu\n", __alignof__ (i));
}
y.c: In function ‘h’:
y.c:21:32: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
21 |   __builtin_printf (g ("%i", "%s"), 123);     // -Wformat
   |                               ~^    ~~~
   |                                |    |
   |                                |    int
   |                                char *
   |                               %d
y.c:22:26: warning: format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘char *’ [-Wformat=]
22 |   __builtin_printf (g ("%i", "%s"), "abc");   // also -Wformat
   |                         ~^          ~~~~~
   |                          |          |
   |                          int        char *
   |                         %s
f103
f105
f10x
alignof (i) = 16