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

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |msebor at gcc dot 
gnu.org
            Summary|[9/10 Regression] ICE in    |[9/10 Regression] ICE on
                   |get_constant, at            |redeclaration of an
                   |c-family/c-format.c:325     |attribute format function
                   |                            |without protoype

--- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> ---
I'm not sure it makes sense to accept attribute format on functions without a
prototype.  It certainly doesn't make sense to keep it after a declaration to
which it can't be applied has been seen.  The only other kind of a declaration
that the attribute can meaningfully be applied is a variadic one but such is
not accepted after one without a prototype.

GCC 8 does accept the attribute on functions without a prototype and even seems
to do behave sensibly for "sensible" calls with the format argument in the
right place, but without -Wformat-nonliteral it doesn't do anything useful if
the format argument is not of the right type (e.g., because it's misplaced)
such as in:

  __attribute__((__format__(__printf__, 1, 2))) void foo ();

  void bar (void)
  {
    foo (1, "%s", 2);   // no warning
  }

(As an aside, not diagnosing at least the call if not the declaration seems
like a bug because GCC doesn't accept attribute format on variadic functions
where the format doesn't have a declared type compatible with char* and where
the first-to-check argument isn't the position of the ellipsis (i.e., it can't
be an arbitrary position within the variable argument list).)

A simple solution is to simply drop the attribute from functions without a
prototype with a warning like Clang does:

  warning: '__format__' attribute only applies to Objective-C
        methods, blocks, and non-K&R-style functions [-Wignored-attributes]

A slightly more involved but less intrusive (to user code) solution is to drop
it when a redeclaration is seen with a prototype.

Reply via email to