https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98733
Bug ID: 98733
Summary: libiberty (v)asprintf checks do not work if asprintf()
is a macro
Product: gcc
Version: 11.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: other
Assignee: unassigned at gcc dot gnu.org
Reporter: tbaeder at redhat dot com
Target Milestone: ---
The include/libiberty.h file has a check before declaring asprintf:
#if defined(HAVE_DECL_ASPRINTF) && !HAVE_DECL_ASPRINTF
extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2;
#endif
via a ac_fn_c_check_decl call in libiberty's configure script,
HAVE_DECL_ASPRINTF is defined when the following code sample compiles without
errors:
#include <stdio.h>
/* ... tons of includes and constant definitions ... */
int
main()
{
(void) asprintf;
return 0;
}
This compiles if asprintf is defined as a function but fails if it is a macro,
which can be tested in this godbolt.org test: https://godbolt.org/z/T5n17c
This is the case for asprintf when stdio.h includes bits/stdio2.h and the
compiler does not support va_arg_pack().
The former happens via stdio.h when the _FORTIFY_SOURCE level is > 0 and
__fortify_function is defined:
https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/stdio.h;h=144137cf67aadac3e86844e37f0fe47c45072fd3;hb=HEAD#l866
and the latter causes the definition of asprintf() as a
macro:https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/bits/stdio2.h;h=3f0cab1254b02c4348dcd961e38b9805c7cbe834;hb=HEAD#l206
Given this combination, HAVE_DECL_ASPRINTF is 0, which means libiberty will in
the end declare its own asprintf, via include/libiberty.h:
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=include/libiberty.h;h=f4c0fe11d6fe3fe0e1cc44c7c6f6266c97c263e4;hb=HEAD#l655
... which will then fail:
../../libiberty/../include/libiberty.h:627:12: error: expected parameter
declarator
extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2;
^
/usr/include/bits/stdio2.h:207:24: note: expanded from macro 'asprintf'
__asprintf_chk (ptr, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
Clang does not support va_arg_pack(), so this failure occurs when using clang.