Yes, the problem is  libiberty is compiling some files
with _GNU_SOURCE defined and some not. So the configure
file does not include "#define _GNU_SOURCE".

I have reduced the failing compiling as below.

#define _GNU_SOURCE                      ////            (1)
#define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m)))
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__,
m, n))) ATTRIBUTE_NONNULL(m)
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
#include <stdio.h>
//#define _GNU_SOURCE                 //               (2)
extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2;

it fails with command line
/usr/bin/clang -fPIE -D_FORTIFY_SOURCE=2 -O2 -c f.c -o f.o

If the _GNU_SOURCE is placed at (1), then the asprintf in the test
case is a macro and it is expanded to

extern int __asprintf_chk (char **, 2 - 1, const char *, ...)
__attribute__ ((__format__ (__printf__, 2, 3))) __attribute__
((__nonnull__ (2)));

in the pre-processed file and causes compilation error.

If the  _GNU_SOURCE is placed at (2) or after stdio.h, then asprintf
in the test case
is still a function in the pre-processed file and it compiles.
extern int asprintf (char **, const char *, ...) __attribute__
((__format__ (__printf__, 2, 3))) __attribute__ ((__nonnull__ (2)));


I then looked at the /usr/include/bits/stdio2.h,  it has
# ifdef __USE_GNU
...
#  ifdef __va_arg_pack
__fortify_function int
__NTH (asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...))
{
  return __asprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt,
                         __va_arg_pack ());
}

__fortify_function int
__NTH (__asprintf (char **__restrict __ptr, const char *__restrict __fmt,
                   ...))
{
  return __asprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt,
                         __va_arg_pack ());
}

__fortify_function int
__NTH (obstack_printf (struct obstack *__restrict __obstack,
                       const char *__restrict __fmt, ...))
{
  return __obstack_printf_chk (__obstack, __USE_FORTIFY_LEVEL - 1, __fmt,
                               __va_arg_pack ());
}
#  elif !defined __cplusplus
#   define asprintf(ptr, ...) \
  __asprintf_chk (ptr, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
#   define __asprintf(ptr, ...) \
  __asprintf_chk (ptr, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
#   define obstack_printf(obstack, ...) \
  __obstack_printf_chk (obstack, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
#  endif
# endif

It requires gcc to be at least 4.3 to have __va_arg_pack defined.
Clang only has gcc 4.2. So clang chooses
the asprintf macro and causes the problem.

On Mon, May 4, 2015 at 5:30 PM, Ian Lance Taylor <i...@google.com> wrote:
> On Mon, May 4, 2015 at 3:49 PM, Yunlian Jiang <yunl...@google.com> wrote:
>> There was a similar disscussion here
>> https://gcc.gnu.org/ml/gcc/2005-11/msg01190.html
>
> That was a discussion about libiberty.  Your subject says you have
> trouble building gdb.
>
> Can you describe the exact problem that you are having?  What
> precisely are you doing?  What precisely happens?
>
>
>> The problem is in the configure stage, the __GNU_SOURCE is not
>> defined, and it could not find
>> the declaration of asprintf. so it make a declaration of asprintf in
>> libiberty.h. And  for the file floatformat.c,
>> the  __GNU_SOURCE is defined, so it could find another asprintf in
>> /usr/include/bits/stdio2.h, it also includes
>> libiberty.h. So these two asprintf conflicts when __USE_FORTIFY_LEVEL is set.
>
> I think the basic guideline should be that HAVE_DECL_ASPRINTF should
> be correct.  If libiberty compiled with _GNU_SOURCE defined, then it
> should test HAVE_DECL_ASPRINTF with _GNU_SOURCE defined.  If not, then
> not.  So perhaps the problem is that libiberty is compiling some files
> with _GNU_SOURCE defined and some not.
>
> Ian

Reply via email to