public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug other/98733] New: libiberty (v)asprintf checks do not work if asprintf() is a macro
@ 2021-01-18 16:24 tbaeder at redhat dot com
  2021-05-10  7:45 ` [Bug other/98733] " tbaeder at redhat dot com
  0 siblings, 1 reply; 2+ messages in thread
From: tbaeder at redhat dot com @ 2021-01-18 16:24 UTC (permalink / raw)
  To: gcc-bugs

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.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Bug other/98733] libiberty (v)asprintf checks do not work if asprintf() is a macro
  2021-01-18 16:24 [Bug other/98733] New: libiberty (v)asprintf checks do not work if asprintf() is a macro tbaeder at redhat dot com
@ 2021-05-10  7:45 ` tbaeder at redhat dot com
  0 siblings, 0 replies; 2+ messages in thread
From: tbaeder at redhat dot com @ 2021-05-10  7:45 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Timm Bäder <tbaeder at redhat dot com> ---
I looked into this problem again and I think a potential fix could be as easy
as...


commit b95eed1938403874be927d4c25b8bbf88ed686ce (HEAD -> master)
Author: Timm Bäder <tbaeder@redhat.com>
Date:   Mon May 10 09:33:26 2021 +0200

    libiberty: Check for asprintf/snprintf macros

    asprintf and snprintf might be defined as a macro, in which case the
    declarations in libiberty.h should be omitted. This is in particular
    true for compilers that do not support __va_arg_pack().

diff --git a/include/libiberty.h b/include/libiberty.h
index f4c0fe11d6f..51a5bf91219 100644
--- a/include/libiberty.h
+++ b/include/libiberty.h
@@ -648,7 +648,7 @@ extern void *bsearch_r (const void *, const void *,
                        int (*)(const void *, const void *, void *),
                        void *);

-#if defined(HAVE_DECL_ASPRINTF) && !HAVE_DECL_ASPRINTF
+#if defined(HAVE_DECL_ASPRINTF) && !HAVE_DECL_ASPRINTF && !defined(asprintf)
 /* Like sprintf but provides a pointer to malloc'd storage, which must
    be freed by the caller.  */

@@ -672,7 +672,7 @@ extern int vasprintf (char **, const char *, va_list)
ATTRIBUTE_PRINTF(2,0);

 extern char *xvasprintf (const char *, va_list) ATTRIBUTE_MALLOC
ATTRIBUTE_PRINTF(1,0);

-#if defined(HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF
+#if defined(HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF && !defined(snprintf)
 /* Like sprintf but prints at most N characters.  */
 extern int snprintf (char *, size_t, const char *, ...) ATTRIBUTE_PRINTF_3;
 #endif



Does that seem like a sensible thing to do on the GCC side?

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-05-10  7:45 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-18 16:24 [Bug other/98733] New: libiberty (v)asprintf checks do not work if asprintf() is a macro tbaeder at redhat dot com
2021-05-10  7:45 ` [Bug other/98733] " tbaeder at redhat dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).