[Bug middle-end/87592] New: overriding attribute constructor and destructor priority not diagnosed

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Oct 11 19:51:00 GMT 2018


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

            Bug ID: 87592
           Summary: overriding attribute constructor and destructor
                    priority not diagnosed
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

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


More information about the Gcc-bugs mailing list