[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#601577: Support for multiple successive format attributes



Package: gcc
Version: 4:4.3.2-2
Severity: wishlist

(This wishlist bug report should probably go upstream.)

Consider the following program:

  void ha(const char *fmt, ...) __attribute__((format(printf,1,2)));

  void haha(const char *fmt, const char *fmt2, ...)
      __attribute__((format(printf,1,3),format(printf,2,3)));

  void ha_ha(const char *fmt, const char *fmt2, ...)
    __attribute__((format(printf,1,3))) __attribute__((format(printf,2,3)));

  void ahah(const char *fmt, const char *fmt2, ...)
      __attribute__((format(printf,2,3),format(printf,1,3)));

  int main(void) {
      ha("%d",1);
      haha("%d", "%f", 1, 2.0);
      ha_ha("%d", "%f", 1, 2.0);
      ahah("%d", "%f", 2.0, 1);
      return 0;
  }

I think the intent of the multiple format specifiers is clear and
there are circumstances where this would be a useful thing to do.

Currently gcc doesn't notice that there's anything weird going on, and
simply handles each format specifier separately.  That's not
unreasonable but it would be better if it didn't reset the argument
counter between the two executions.

It would be fine if this only worked if you specified all the formats
in one __attribute__ declaration, but it would be better still if you
could specify them separately.

The order of the variadic arguments should be the order in which the
format attributes are declared, _not_ the order in which the format
arguments appear (if they are different).

Compatibility note: this will break existing programs which
unintentionally declare identical format attributes multiple times.
A possible workaround for this would be to de-dupe the format
attributes according to the format argument number, at the cost of not
being able to support functions which use the same format argument to
format multiple successive sets of variadic arguments.

Partial workaround: specifying -1 as the variadic argument index for
both formats will allow the compiler to at least check the format
strings.


Just for completeness, actual output:

  $ gcc -Wall -c t.c
  t.c: In function 'main':
  t.c:14: warning: format '%f' expects type 'double', but argument 3 has
  type 'int'
  t.c:14: warning: too many arguments for format
  t.c:14: warning: too many arguments for format
  t.c:15: warning: format '%f' expects type 'double', but argument 3 has
  type 'int'
  t.c:15: warning: too many arguments for format
  t.c:15: warning: too many arguments for format
  t.c:16: warning: too many arguments for format
  t.c:16: warning: format '%d' expects type 'int', but argument 3 has
  type 'double'
  t.c:16: warning: too many arguments for format
  $

Desired output:

  $ gcc -Wall -c t.c
  $

Less optimal desired output:

  $ gcc -Wall -c t.c
  t.c:6: error: multiple formats must appear in a single __attribute__
  $

Or perhaps, if appropriately documented:

  $ gcc -Wall -c t.c
  t.c:15: warning: format '%f' expects type 'double', but argument 3 has
  type 'int'
  t.c:15: warning: too many arguments for format
  t.c:15: warning: too many arguments for format
  $

Ian.



Reply to: