Branch: refs/heads/blead
  Home:   https://github.com/Perl/perl5
  Commit: 49d95ca1ee334d8e21c99ee32e02771ca55f1a46
      
https://github.com/Perl/perl5/commit/49d95ca1ee334d8e21c99ee32e02771ca55f1a46
  Author: Lukas Mai <lukasmai....@gmail.com>
  Date:   2024-02-11 (Sun, 11 Feb 2024)

  Changed paths:
    M locale.c

  Log Message:
  -----------
  locale.c: fix format type for __LINE__ output (debugging)

On some platforms, building a -DDEBUGGING perl triggers the following
compiler warnings:

    In file included from locale.c:385:
    locale.c: In function ‘S_bool_setlocale_2008_i’:
    locale.c:2494:29: warning: format ‘%lu’ expects argument of type ‘long 
unsigned int’, but argument 7 has type ‘int’ [-Wformat=]
                                 "bool_setlocale_2008_i: creating new object"   
 \
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    perl.h:4983:33: note: in definition of macro ‘DEBUG__’
                     DEBUG_PRE_STMTS a; DEBUG_POST_STMTS                     \
                                     ^
    locale.c:2493:7: note: in expansion of macro ‘DEBUG_L’
           DEBUG_L(PerlIO_printf(Perl_debug_log,                                
 \
           ^~~~~~~
    locale.c:2523:17: note: in expansion of macro ‘DEBUG_NEW_OBJECT_FAILED’
                     DEBUG_NEW_OBJECT_FAILED(category_names[index], new_locale,
                     ^~~~~~~~~~~~~~~~~~~~~~~
    In file included from locale.c:322:
    config.h:4052:18: note: format string is defined here
     #define U32uf  "lu"  /**/

This is because the code tries to format __LINE__ with a varargs
function using %"LINE_Tf".

Things are slightly tricky here because in a varargs function, no type
context is available, so the format string absolutely has to match the
intrinsic type of each argument. The __LINE__ macro expands to a simple
(decimal) integer constant. According to C, such a constant has type int
if its value fits, otherwise unsigned int if it fits, otherwise long
int, etc. None of the *.c files in the perl distribution exceed 32767
lines (the minimum INT_MAX required by C), so even on ancient 16-bit
systems, our __LINE__ will always be of type int.

The %"LINE_Tf" format is designed to match a line_t argument, not int.
(On some platforms, line_t is defined as unsigned long and incompatible
with int for formatting purposes.) Therefore it is an error to use
%"LINE_Tf" with __LINE__.

One way to fix this is to convert the argument to match the format
string: ... %"LINE_Tf" ...", (line_t)__LINE__.

The other way is to change the format string to match the (int)
argument: "... %d ...", __LINE__.

Option 1 is what is used elsewhere in locale.c, so use line_t
consistently for all line numbers.


Reply via email to