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