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

            Bug ID: 78703
           Summary: -fprintf-return-value floating point handling
                    incorrect in locales with a mulltibyte decimal point
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

POSIX specifies that:

All forms of the fprintf() functions allow for the insertion of a
language-dependent radix character in the output string.  The radix character
is defined in the current locale (category LC_NUMERIC).  In the POSIX locale,
or in a locale where the radix character is not defined, the radix character
shall default to a <period> ('.')

Similar wording is in buried in C which defines the decimal-point character in
7.1.1, p2 (as noted in bug 78696, comment 5).

The following test case derived from bug 78696, comment 3, shows that the
-fprintf-return-value optimization assumes the call is made in the POSIX
locale.  The optimization needs to avoid making this assumption.  To be safe,
it needs to conservatively assume that the length of the decimal point
character is up to MB_LEN_MAX bytes.

$ cat zz.c && gcc -O2 -Wformat zz.c && LC_ALL='ps_AF.UTF-8' ./a.out
#include <locale.h>

#define FMT "%.2f"
const char *fmt = FMT;

int main (void)
{
  if (!setlocale (LC_ALL, ""))
    return 1;

  int m = __builtin_snprintf (0, 0, FMT, 1.5);   // computed by GCC
  int n = __builtin_snprintf (0, 0, fmt, 1.5);   // computed by libc

  __builtin_printf ("%i == %i\n", m, n);
}

4 == 5

Reply via email to