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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |ice-on-invalid-code
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |msebor at gcc dot 
gnu.org

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
GCC accepts the invalid redeclaration of the built-in.  GCC 8 silently, but GCC
9 and 10 diagnose it albeit only with -Wextra (see below).  No version prevents
it from being treated as a built-in, which is what in GCC 9 and 10 then causes
trouble when the function is called.  As in previous reports of ICE's of this
sort (most recently 93926), this is due to a mismatch of expectations between
different parts of the compiler.  In this case between the handling of calls to
the built-in that are expected to pass the validation of the format attribute
because the validation of the built-in declaration is assumed to have passed
earlier.  When the invalid redeclaration is allowed to replace the valid one
GCC sets up internally, the expectation isn't justified.

I can think of three ways to resolve this: either (1) the invalid redeclaration
needs to cause calls to the function to be treated as those to ordinary
non-built-ins, or (2) the attribute needs to be removed from it, or (3) the
call validation should not be expected to pass.

(3) seems like the least intrusive option but it doesn't quite go far enough. 
Although with the validation removed the ICE is gone, the code then fails to
compile with an error later due to the mismatch between the attribute and the
type of the argument.

To be fully general, (2) would require revalidating all attributes between on
built-in redeclarations and removing incompatibilities.  That seems like a
fairly intrusive change.  

In view of that, the simplest and most robust solution is (1).  Let me work on
it.

$ gcc -O2 -Wall -Wextra  -S pr94040.c
pr94040.c:8:1: warning: mismatch in argument 3 type of built-in function
‘strftime’; expected ‘const char *’ [-Wbuiltin-declaration-mismatch]
    8 | strftime (char *, __SIZE_TYPE__, int *, struct tm *);
      | ^~~~~~~~
pr94040.c:1:1: note: ‘strftime’ is declared in header ‘<time.h>’
  +++ |+#include <time.h>
    1 | struct tm
pr94040.c: In function ‘foo’:
pr94040.c:13:10: warning: null argument where non-null required (argument 3)
[-Wnonnull]
   13 |   return strftime (p, 0, 0, t);
      |          ^~~~~~~~
pr94040.c:13:3: error: ‘format’ attribute argument 2 value ‘3’ refers to
parameter type ‘int *’
   13 |   return strftime (p, 0, 0, t);
      |   ^~~~~~
pr94040.c:13:3: internal compiler error: in get_constant, at
c-family/c-format.c:325

Reply via email to