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; }