Hi Bruno,

On 4/27/24 2:02 AM, Bruno Haible wrote:
> At this point of the investigations, it's too early for a patch.
> First, one needs to determine whether it's a bug in Gnulib or a
> bug in some package we rely on (typically gcc or glibc). In the
> latter case, we report the bug and wait for the answer. Depending
> on the answer, we may fix the test (if they say that our test is
> wrong), or we may put in an officially recommended workaround,
> or a workaround of our liking, or disable that part of the unit test.

Sounds like a lot of things to learn.

> If some glibc-optimized expansions are active, you would also see some
> *_chk symbols in the 'nm' output.

Interesting, I didn't know that is how you could tell. Thanks!

> So, at this point it looks like a gcc problem. The next step is to prepare
> a trimmed-down test case <https://gcc.gnu.org/bugs/#need>:
>   1. Concentrate on the simpler test case. In this case, I would say, it's
>      sprintf, since it takes one argument less than snprintf.
>   2. Eliminate the -I, -L, -l options specific to gnulib. So that you have
>      a program that succeeds without -O2 and fails with -O2. This implies
>      inlining include files from gnulib (test-sprintf-posix.h, macros.h, 
> etc.).
>   3. Work on minimizing the compilation unit that succeeds without -O2 and
>      fails with -O2. Always keep -Wall enabled, to guard against mistakes.
>      Remove the test cases that pass, remove unnecessary includes, and so on.
>   4. When you can't minimize that further, preprocess it:
>      $ gcc OPTIONS -E foo.c > foo-pre.c
>      Verify that it still succeeds without -O2 and fails with -O2.
>   5. Continue minimizing, with -Wall enabled. Typically the end result will
>      be a small file, 10-20 lines of code.
> 
> If you got that far and can argue (by the standards) that it is a GCC bug,
> open a bug report. The GCC shipped by Fedora is not an upstream release;
> nevertheless Paul opens his bug reports about Fedora's gcc directly in the
> upstream bug tracker, e.g.
> <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114870?>. You can do the same.

Thanks for the information! I did a little expirementing with this program:

====================================================================
#include <stdio.h>
#include <wchar.h>

int
main (void)
{
  char buffer[5000];
  wint_t ch = (wint_t) L'\0';
  int result = sprintf (buffer, "%lc%lc%lc%lc", ch, ch, ch, ch);
  printf ("%d\n", result);
  return 0;
}
====================================================================

I think I did decent at narrowing it down:

    $ make
    gcc -Wall -g -O2 -fprintf-return-value -o a.out main.c
    ./a.out
    0
    $ make
    gcc -Wall -g -O0 -o a.out main.c
    ./a.out
    4
    $ make
    gcc -Wall -g -O1 -o a.out main.c
    ./a.out
    0
    $ make
    gcc -Wall -g -O1 -fprintf-return-value -o a.out main.c
    ./a.out
    0
    $ make
    gcc -Wall -g -O1 -fno-printf-return-value -o a.out main.c
    ./a.out
    4

If I understand correctly, sprintf should return 4 here correct? And
the buffer should have 5 NUL bytes. 4 from the arguments and 1
trailing, which is excluded from the return value.

Collin

Reply via email to