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

            Bug ID: 87593
           Summary: conflicting format_arg attributes on a declaration
                    accepted
           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: ---

As mentioned in pr87592, 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.

It's possible to have a format_arg function return one or the other argument so
allowing format_arg to specify multiple arguments isn't completely meaningless,
but it seems unlikely, and it's almost certainly a mistake when the attributes
are on distinct declarations of the same function.  So issuing a warning
pointing out this likely mistake would seem appropriate.  Documenting the
effect of such apparently conflicting attributes would be worthwhile in any
case.

$ cat y.c && gcc -S -Wall y.c

__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
}
y.c: In function ‘h’:
y.c:7:32: warning: format ‘%s’ expects argument of type ‘char *’, but argument
2 has type ‘int’ [-Wformat=]
7 |   __builtin_printf (g ("%i", "%s"), 123);     // -Wformat
  |                               ~^    ~~~
  |                                |    |
  |                                |    int
  |                                char *
  |                               %d
y.c:8:26: warning: format ‘%i’ expects argument of type ‘int’, but argument 2
has type ‘char *’ [-Wformat=]
8 |   __builtin_printf (g ("%i", "%s"), "abc");   // also -Wformat
  |                         ~^          ~~~~~
  |                          |          |
  |                          int        char *
  |                         %s

Reply via email to