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

            Bug ID: 104380
           Summary: -D_FORTIFY_SOURCE -mabi=ieeelongdouble -std=c*
                    wrong-code
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jakub at gcc dot gnu.org
  Target Milestone: ---

With -O2 -D_FORTIFY_SOURCE=2 -mabi=ieeelongdouble -std=c11 (or some other
-std=c* mode), the following testcase fails on powerpc64le-linux:

#include <stdio.h>
#include <stdarg.h>

static char buf[4096];
static char gfmt[] = "%Lg";

static int __attribute__ ((noinline))
foo (char *str, const char *fmt, ...)
{
  int ret;
  va_list ap;
  va_start (ap, fmt);
  ret = vsnprintf (str, 4096, fmt, ap);
  va_end (ap);
  return ret;
}

int
main ()
{
  long double dval = 128;
  int ret = foo (buf, gfmt, dval);
  if (ret != 3 || __builtin_strcmp (buf, "128") != 0)
    __builtin_abort ();
  return 0;
}

It works without -D_FORTIFY_SOURCE*, or with the GNU standard modes (-std=gnu99
etc.).
Preprocessed and reduced it is:
extern int vsnprintf (char *__restrict __s, size_t __maxlen, const char
*__restrict __format, __builtin_va_list __arg)
  __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3,
0)));
extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag,
size_t __slen, const char *__restrict __format, __builtin_va_list __ap)
  __attribute__ ((__nothrow__ , __leaf__));
extern __inline __attribute__ ((__always_inline__)) __attribute__
((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) vsnprintf (char *__restrict __s,
size_t __n, const char *__restrict __fmt, __builtin_va_list __ap)
{
  return __builtin___vsnprintf_chk (__s, __n, 2 - 1, __builtin_object_size
(__s, 2 > 1), __fmt, __ap);
}
extern __typeof (vsnprintf) vsnprintf __asm ("__vsnprintfieee128");
extern __typeof (__vsnprintf_chk) __vsnprintf_chk __asm
("__vsnprintf_chkieee128");

static char buf[4096];
static char gfmt[] = "%Lg";

static int __attribute__ ((noinline))
foo (char *str, const char *fmt, ...)
{
  int ret;
  __builtin_va_list ap;
  __builtin_va_start (ap, fmt);
  ret = vsnprintf (str, 4096, fmt, ap);
  __builtin_va_end (ap);
  return ret;
}

int
main ()
{
  long double dval = 128;
  int ret = foo (buf, gfmt, dval);
  if (ret != 3 || __builtin_strcmp (buf, "128") != 0)
    __builtin_abort ();
  return 0;
}

Reply via email to