Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No subject provided #951

Closed
p5pRT opened this issue Dec 15, 1999 · 12 comments
Closed

No subject provided #951

p5pRT opened this issue Dec 15, 1999 · 12 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 15, 1999

Migrated from rt.perl.org#1896 (status was 'resolved')

Searchable as RT1896$

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 1999

From rmb1@cise.npl.co.uk

Created by rmb1@tempest.cise.npl.co.uk

pragma/warnings failed​:
PROG​:
# regcomp.c [S_regclass S_regclassutf8]
use warnings 'unsafe' ;
$a =~ /[a\zb]/ ;
no warnings 'unsafe' ;
$a =~ /[a\zb]/ ;
EXPECTED​:
/[a\zb]/​: Unrecognized escape \z in character class passed through at - line 3.
GOT​:
/[a\zb]/​: Unrecognized escape \ in character class passed through at - line 3.
FAILED at test 247

I tracked this down, after several blind alleys, to the variable containing
the missing 'z' being a UV; which did not work correctly with the %c format.

Patch below​: perhaps '(char)' should be '(int)' for consistency.

Robin

--- regcomp.c 1999/12/15 11​:13​:22 1.1
+++ regcomp.c 1999/12/15 13​:02​:10 1.2
@​@​ -2918,7 +2918,7 @​@​
  Perl_warner(aTHX_ WARN_UNSAFE,
  "/%.127s/​: Unrecognized escape \\%c in character class passed through",
  PL_regprecomp,
- value);
+ (char)value);
  break;
  }
  }

Perl Info


Site configuration information for perl 5.00563:

Configured by rmb1 at Mon Dec 13 17:41:12 GMT 1999.

Summary of my perl5 (revision 5.0 version 5 subversion 63) configuration:
  Platform:
    osname=solaris, osvers=2.7, archname=sun4-solaris
    uname='sunos tempest 5.7 generic_106541-04 sun4u sparc sunw,ultra-5_10 '
    config_args=''
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef useperlio=define d_sfio=undef
    use64bits=define usemultiplicity=undef
  Compiler:
    cc='cc', optimize='-O', gccversion=2.95.1 19990816 (release)
    cppflags='-fno-strict-aliasing -I/usr/local/include -I/opt/gnu/include'
    ccflags ='-fno-strict-aliasing -I/usr/local/include -I/opt/gnu/include -DUSE_LONG_LONG -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    stdchar='char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    alignbytes=8, usemymalloc=y, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib -L/opt/gnu/lib '
    libpth=/usr/local/lib /opt/gnu/lib /lib /usr/lib /usr/ccs/lib
    libs=-lsocket -lnsl -ldl -lm -lc -lcrypt -lsec
    libc=/lib/libc.so, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-fPIC', lddlflags='-G -L/usr/local/lib -L/opt/gnu/lib'

Locally applied patches:
    


@INC for perl 5.00563:
    ./lib
    /home/rmb1/appl/lib/perl5/site_perl/5.005/sun4-solaris
    /home/rmb1/appl/lib/perl5/site_perl/5.005
    /home/rmb1/appl/lib/perl5/5.00563/sun4-solaris
    /home/rmb1/appl/lib/perl5/5.00563
    /home/rmb1/appl/lib/site_perl/5.00563/sun4-solaris
    /home/rmb1/appl/lib/site_perl
    .


Environment for perl 5.00563:
    HOME=/home/rmb1
    LANG=C
    LANGUAGE (unset)
    LD_LIBRARY_PATH=/usr/lib
    LOGDIR (unset)
    PATH=/home/rmb1/appl/script:/opt/gnu/script:/opt/gnu/bin:/opt/misc/bin:/usr/appl/script:/usr/local/appl/bin:/usr/tempest/bin:/usr/local/bin:/usr/local/Admigration/exec:/usr/local/hotjava/bin:/usr/openwin/bin:/usr/dt/bin:/usr/ccs/bin:/usr/bin
    PERL5LIB=/home/rmb1/appl/lib/perl5/site_perl/5.005
    PERL_BADLANG (unset)
    SHELL=/bin/csh

-- 
Robin Barker,                     \  Email: Robin.Barker@npl.co.uk
Information Systems Engineering,   \  Tel:    +44 (0) 20 8943 7090
B10, National Physical Laboratory,  \  Fax:   +44 (0) 20 8977 7091
Teddington, Middlesex, UK. TW11 0LW  \  WWW:  http://www.npl.co.uk

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 1999

From [Unknown Contact. See original ticket]

Further investigation of the printf function with UVs reveals​:

#include <stdio.h>
int main () {
  long long int foo = 1L;
  long long int bar = 2L;
  printf( "%d %d %d %d\n", foo, bar);
}

gives output​:
0 1 0 2

This is gcc-2.95.1 on sun4-solaris2.7

The conclusion is that failure to cast UV/IV before using %d
will not only produce wrong output,
but will cause printf to get out of step with its arguments.

Robin

--
Robin Barker, \ Email​: Robin.Barker@​npl.co.uk
Information Systems Engineering, \ Tel​: +44 (0) 20 8943 7090
B10, National Physical Laboratory, \ Fax​: +44 (0) 20 8977 7091
Teddington, Middlesex, UK. TW11 0LW \ WWW​: http​://www.npl.co.uk

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 1999

From [Unknown Contact. See original ticket]

At 05​:57 PM 12/15/99 +0000, Robin Barker wrote​:

Further investigation of the printf function with UVs reveals​:

#include <stdio.h>
int main () {
long long int foo = 1L;
long long int bar = 2L;
printf( "%d %d %d %d\n", foo, bar);
}

Not to be too pedantic here, but...

This is illegal code, and it's subject to the whims and vagaries of your
OS/chip/compiler combination. It's a compilation error under Dec^WCompaq C,
for example.

How it behaves depends on quite a number of factors. The output I get, for
example, is​:

1 2 2062686916 2062686912

but in a more complex program this sort of thing tends to cause access
violations. My calling convention's to put some arguments in registers, and
I think some machines will cast all the integers to quadwords and end up
popping 16 bytes too much off the stack and eventually causing the program
to die with a corrupted stack.

Not to say the problem's not real, but this program isn't a good
illustration of it.

  Dan

----------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
dan@​sidhe.org have teddy bears and even
  teddy bears get drunk

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 1999

From [Unknown Contact. See original ticket]

#include <stdio.h>
int main () {
long long int foo = 1L;
long long int bar = 2L;
printf( "%d %d %d %d\n", foo, bar);
}

Not to be too pedantic here, but...

This is illegal code, and it's subject to the whims and vagaries of your
OS/chip/compiler combination. It's a compilation error under Dec^WCompaq C,
for example.

How it behaves depends on quite a number of factors. The output I get, for
example, is​:

1 2 2062686916 2062686912

If you want legal code, here's some legal code​:

#include <stdio.h>
int main () {
  long long int foo = 1L;
  long long int bar = 2L;
  printf( "%d %d\n", foo, bar);
}

On my machine this gives
0 1

and on your machine gives (I presume)
1 2

The fact remains that we must detect/fix this gcc bug/feature or
avoid using printf("%d",x) where x is a UV/IV and could be longer
than %d is expecting.

Robin

--
Robin Barker | Eail​: Robin.Barker@​npl.co.uk
CISE, Building 10, | Phone​: +44 (0) 20 8943 7090
National Physical Laboratory, | Fax​: +44 (0) 20 8977 7091
Teddington, Middlesex, UK. TW11 OLW | WWW​: http​://www.npl.co.uk

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 1999

From [Unknown Contact. See original ticket]

At 12​:04 PM 12/16/99 +0000, Robin Barker wrote​:

If you want legal code, here's some legal code​:

#include <stdio.h>
int main () {
long long int foo = 1L;
long long int bar = 2L;
printf( "%d %d\n", foo, bar);
}

On my machine this gives
0 1

and on your machine gives (I presume)
1 2

Yep. And the compiler yells that the types of the arguments don't match the
format string. (I do like compile-time printf arg checks... :)

The fact remains that we must detect/fix this gcc bug/feature or
avoid using printf("%d",x) where x is a UV/IV and could be longer
than %d is expecting.

Yep, we do need to root out those. We really need to go and do some
generalization everywhere, since this is a general problem--when printf
arguments don't match what's expected in the format string Bad Things Can
Happen.

More preprocessor abuse, I'd expect. :(

  Dan

----------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
dan@​sidhe.org have teddy bears and even
  teddy bears get drunk

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 1999

From [Unknown Contact. See original ticket]

More preprocessor abuse, I'd expect. :(

Well, since we already only compile with ansi C, I don't know if it would
be abuse or not. Something like​:

  printf("%d blah blah blah %d",x,y)

could change to

  printf(Perl_IV_FMT " blah blah blah " Perl_IV_FMT, x, y)

where Perl_IV_FMT is whatever the appropriate string might be for formatting
an IV value, etc. Then the automagic concatenation of string literals that
ansi C calls for will get the right format string built by the compiler.

I was quite surprised that C committee didn't predefine format strings like
this for all the various built in types they mandated (how do you know how
to printf a size_t, for instance?).

Of course, someone still has to find and fix all of 'em :-).
--
Tom.Horsley@​mail.ccur.com \\\\ Will no one rid me of
Concurrent Computers, Ft. Lauderdale, FL \\\\ this troublesome
Me​: http​://home.att.net/~Tom.Horsley/ \\\\ autoconf?
Project Vote Smart​: http​://www.vote-smart.org \\\\ !!!!!

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 1999

From [Unknown Contact. See original ticket]

At 09​:05 AM 12/16/99 -0500, Tom Horsley wrote​:

More preprocessor abuse, I'd expect. :(

Well, since we already only compile with ansi C, I don't know if it would
be abuse or not. Something like​:

printf("%d blah blah blah %d",x,y)

could change to

printf(Perl_IV_FMT " blah blah blah " Perl_IV_FMT, x, y)

where Perl_IV_FMT is whatever the appropriate string might be for formatting
an IV value, etc. Then the automagic concatenation of string literals that
ansi C calls for will get the right format string built by the compiler.

That's what I was figuring we'd do. I was also thinking it'd add another
layer of preprocessor indirection. At some point I think I'll go see how
deep the deepest gets--I think I saw an eight level substitution in one of
the thread builds...

  Dan

----------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
dan@​sidhe.org have teddy bears and even
  teddy bears get drunk

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 1999

From @vanstyn

In <14424.61869.887887.427597@​cleo.ccur.com>, Tom Horsley writes​:
:I was quite surprised that C committee didn't predefine format strings like
:this for all the various built in types they mandated (how do you know how
:to printf a size_t, for instance?).

For a long time, I've cast all such unknown sizes to long for formatting,
but I now wonder (with the rise of new types such as 'long long') whether
I've done the right thing.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 1999

From [Unknown Contact. See original ticket]

Hugo <hv@​crypt.compulink.co.uk> wrote

In <14424.61869.887887.427597@​cleo.ccur.com>, Tom Horsley writes​:
:I was quite surprised that C committee didn't predefine format strings like
:this for all the various built in types they mandated (how do you know how
:to printf a size_t, for instance?).

For a long time, I've cast all such unknown sizes to long for formatting,
but I now wonder (with the rise of new types such as 'long long') whether
I've done the right thing.

It's a pity that C doesn't define a type 'longest' for this purpose. :-)

Mike Guy

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 1999

From [Unknown Contact. See original ticket]

In message <E11yfBK-0006mz-00@​ursa.cus.cam.ac.uk>
  "M.J.T. Guy" <mjtg@​cus.cam.ac.uk> wrote​:

It's a pity that C doesn't define a type 'longest' for this purpose. :-)

#include <inttypes.h>

intmax_t x;

Of course you do need a ISO C99 compliant compiler ;-)

Tom

--
Tom Hughes (tom@​compton.nu)
http​://www.compton.nu/
...Any fool can tell the truth, but a man of sense can lie well.

@p5pRT
Copy link
Author

p5pRT commented Dec 17, 1999

From [Unknown Contact. See original ticket]

I dno't know if this is of any interest or any use.

I investigated the possible type errors further.

The attached patch adds code for checking printf formats using -DCHECK_FORMAT​:
- it adds attributes for format checking in proto.h (via embed.h)
- it replaces "%_" by "%"SVf which become "%p" with -DCHECK_FORMAT
- without -DCHECK_FORMAT the patch should be effectively NOOP

Applying the patch, configuring with -Dccflags="-Wformat -DCHECK_FORMAT",
and <make>ing gives the following. <make test> fails some tests because
"%p" does not give the same results as "%_"! I haven't tried to fix the
format type errors​: I am not sure which should be casts on the data or
change to matching format.

toke.c​: In function `S_scan_const'​:
toke.c​:1367​: warning​: field width is not type int (arg 3)
toke.c​:1367​: warning​: field width is not type int (arg 5)
op.c​: In function `Perl_pmtrans'​:
op.c​:2651​: warning​: unsigned int format, U32 arg (arg 3)
op.c​:2651​: warning​: unsigned int format, U32 arg (arg 4)
op.c​:2653​: warning​: unsigned int format, U32 arg (arg 3)
op.c​:2657​: warning​: unsigned int format, U32 arg (arg 3)
op.c​:2657​: warning​: unsigned int format, long unsigned int arg (arg 4)
op.c​:2657​: warning​: unsigned int format, U32 arg (arg 5)
op.c​:2659​: warning​: unsigned int format, U32 arg (arg 3)
op.c​:2659​: warning​: unsigned int format, U32 arg (arg 4)
op.c​: In function `S_cv_dump'​:
op.c​:3992​: warning​: int format, I32 arg (arg 3)
op.c​: In function `Perl_ck_defined'​:
op.c​:5511​: warning​: use of `h' length character with `a' type character
op.c​:5511​: warning​: too few arguments for format
regcomp.c​: In function `S_regclass'​:
regcomp.c​:2921​: warning​: int format, different type arg (arg 4)
regcomp.c​: In function `S_regclassutf8'​:
regcomp.c​:3350​: warning​: field width is not type int (arg 3)
regcomp.c​:3353​: warning​: field width is not type int (arg 3)
regcomp.c​:3394​: warning​: int format, different type arg (arg 4)
regcomp.c​: In function `Perl_regprop'​:
regcomp.c​:3909​: warning​: int format, long int arg (arg 3)
dump.c​: In function `Perl_dump_sub'​:
dump.c​:83​: warning​: unsigned int format, long unsigned int arg (arg 4)
dump.c​:83​: warning​: int format, I32 arg (arg 5)
dump.c​: In function `Perl_do_op_dump'​:
dump.c​:395​: warning​: int format, long int arg (arg 4)
dump.c​: In function `Perl_do_magic_dump'​:
dump.c​:702​: warning​: int format, I32 arg (arg 4)
dump.c​: In function `Perl_do_sv_dump'​:
dump.c​:784​: warning​: field width is not type int (arg 5)
dump.c​:784​: warning​: field width is not type int (arg 8)
dump.c​:1090​: warning​: long long unsigned int format, different type arg (arg 4)
dump.c​:1112​: warning​: int format, I32 arg (arg 4)
pp.c​: In function `Perl_pp_unpack'​:
pp.c​:3984​: warning​: unknown conversion type character `V' in format
pp.c​:3984​: warning​: too many arguments for format
doio.c​: In function `Perl_do_open9'​:
doio.c​:219​: warning​: field width is not type int (arg 2)
op.c​: In function `Perl_pmtrans'​:
op.c​:2651​: warning​: unsigned int format, U32 arg (arg 3)
op.c​:2651​: warning​: unsigned int format, U32 arg (arg 4)
op.c​:2653​: warning​: unsigned int format, U32 arg (arg 3)
op.c​:2657​: warning​: unsigned int format, U32 arg (arg 3)
op.c​:2657​: warning​: unsigned int format, long unsigned int arg (arg 4)
op.c​:2657​: warning​: unsigned int format, U32 arg (arg 5)
op.c​:2659​: warning​: unsigned int format, U32 arg (arg 3)
op.c​:2659​: warning​: unsigned int format, U32 arg (arg 4)
op.c​: In function `S_cv_dump'​:
op.c​:3992​: warning​: int format, I32 arg (arg 3)
op.c​: In function `Perl_ck_defined'​:
op.c​:5511​: warning​: use of `h' length character with `a' type character
op.c​:5511​: warning​: too few arguments for format

Robin

--- XSUB.h 1999/12/17 10​:14​:41 1.1
+++ XSUB.h 1999/12/17 11​:57​:11 1.2
@​@​ -74,7 +74,7 @​@​
  vn = "VERSION"), FALSE); \
  } \
  if (tmpsv && (!SvOK(tmpsv) || strNE(XS_VERSION, SvPV(tmpsv, n_a)))) \
- Perl_croak(aTHX_ "%s object version %s does not match %s%s%s%s %_", \
+ Perl_croak(aTHX_ "%s object version %s does not match %s%s%s%s %"SVf,\
  module, XS_VERSION, \
  vn ? "$" : "", vn ? module : "", vn ? "​::" : "", \
  vn ? vn : "bootstrap parameter", tmpsv); \
--- embed.pl 1999/12/16 16​:45​:11 1.1
+++ embed.pl 1999/12/17 11​:57​:11 1.2
@​@​ -134,6 +134,14 @​@​
  }
  $ret .= ")";
  $ret .= " __attribute__((noreturn))" if $flags =~ /r/;
+ if( $flags =~ /f/ ) {
+ my $prefix = $flags =~ /n/ ? '' : 'pTHX_';
+ my $args = scalar @​args;
+ $ret .= "\n#ifdef CHECK_FORMAT\n";
+ $ret .= sprintf " __attribute__((format(printf,%s%d,%s%d)))",
+ $prefix, $args - 1, $prefix, $args;
+ $ret .= "\n#endif\n";
+ }
  $ret .= ";\n";
  }
  $ret;
@​@​ -1119,22 +1127,22 @​@​
p |MAGIC* |condpair_magic |SV *sv
#endif
p |OP* |convert |I32 optype|I32 flags|OP* o
-pr |void |croak |const char* pat|...
+fpr |void |croak |const char* pat|...
pr |void |vcroak |const char* pat|va_list* args
#if defined(PERL_IMPLICIT_CONTEXT)
-nrp |void |croak_nocontext|const char* pat|...
-np |OP* |die_nocontext |const char* pat|...
-np |void |deb_nocontext |const char* pat|...
-np |char* |form_nocontext |const char* pat|...
-np |SV* |mess_nocontext |const char* pat|...
-np |void |warn_nocontext |const char* pat|...
-np |void |warner_nocontext|U32 err|const char* pat|...
-np |SV* |newSVpvf_nocontext|const char* pat|...
-np |void |sv_catpvf_nocontext|SV* sv|const char* pat|...
-np |void |sv_setpvf_nocontext|SV* sv|const char* pat|...
-np |void |sv_catpvf_mg_nocontext|SV* sv|const char* pat|...
-np |void |sv_setpvf_mg_nocontext|SV* sv|const char* pat|...
-np |int |fprintf_nocontext|PerlIO* stream|const char* fmt|...
+fnrp |void |croak_nocontext|const char* pat|...
+fnp |OP* |die_nocontext |const char* pat|...
+fnp |void |deb_nocontext |const char* pat|...
+fnp |char* |form_nocontext |const char* pat|...
+fnp |SV* |mess_nocontext |const char* pat|...
+fnp |void |warn_nocontext |const char* pat|...
+fnp |void |warner_nocontext|U32 err|const char* pat|...
+fnp |SV* |newSVpvf_nocontext|const char* pat|...
+fnp |void |sv_catpvf_nocontext|SV* sv|const char* pat|...
+fnp |void |sv_setpvf_nocontext|SV* sv|const char* pat|...
+fnp |void |sv_catpvf_mg_nocontext|SV* sv|const char* pat|...
+fnp |void |sv_setpvf_mg_nocontext|SV* sv|const char* pat|...
+fnp |int |fprintf_nocontext|PerlIO* stream|const char* fmt|...
#endif
p |void |cv_ckproto |CV* cv|GV* gv|char* p
p |CV* |cv_clone |CV* proto
@​@​ -1151,7 +1159,7 @​@​
p |U32* |get_opargs
p |PPADDR_t*|get_ppaddr
p |I32 |cxinc
-p |void |deb |const char* pat|...
+fp |void |deb |const char* pat|...
p |void |vdeb |const char* pat|va_list* args
p |void |debprofdump
p |I32 |debop |OP* o
@​@​ -1160,7 +1168,7 @​@​
p |char* |delimcpy |char* to|char* toend|char* from \
  |char* fromend|int delim|I32* retlen
p |void |deprecate |char* s
-p |OP* |die |const char* pat|...
+fp |OP* |die |const char* pat|...
p |OP* |vdie |const char* pat|va_list* args
p |OP* |die_where |char* message|STRLEN msglen
p |void |dounwind |I32 cxix
@​@​ -1225,7 +1233,7 @​@​
#endif
p |OP* |force_list |OP* arg
p |OP* |fold_constants |OP* arg
-p |char* |form |const char* pat|...
+fp |char* |form |const char* pat|...
p |char* |vform |const char* pat|va_list* args
p |void |free_tmps
p |OP* |gen_constant_list|OP* o
@​@​ -1400,7 +1408,7 @​@​
#if defined(USE_LOCALE_COLLATE)
p |char* |mem_collxfrm |const char* s|STRLEN len|STRLEN* xlen
#endif
-p |SV* |mess |const char* pat|...
+fp |SV* |mess |const char* pat|...
p |SV* |vmess |const char* pat|va_list* args
p |void |qerror |SV* err
p |int |mg_clear |SV* sv
@​@​ -1488,7 +1496,7 @​@​
p |SV* |newSVnv |NV n
p |SV* |newSVpv |const char* s|STRLEN len
p |SV* |newSVpvn |const char* s|STRLEN len
-p |SV* |newSVpvf |const char* pat|...
+fp |SV* |newSVpvf |const char* pat|...
p |SV* |vnewSVpvf |const char* pat|va_list* args
p |SV* |newSVrv |SV* rv|const char* classname
p |SV* |newSVsv |SV* old
@​@​ -1659,7 +1667,7 @​@​
p |void |sv_add_arena |char* ptr|U32 size|U32 flags
p |int |sv_backoff |SV* sv
p |SV* |sv_bless |SV* sv|HV* stash
-p |void |sv_catpvf |SV* sv|const char* pat|...
+fp |void |sv_catpvf |SV* sv|const char* pat|...
p |void |sv_vcatpvf |SV* sv|const char* pat|va_list* args
p |void |sv_catpv |SV* sv|const char* ptr
p |void |sv_catpvn |SV* sv|const char* ptr|STRLEN len
@​@​ -1702,7 +1710,7 @​@​
p |void |sv_replace |SV* sv|SV* nsv
p |void |sv_report_used
p |void |sv_reset |char* s|HV* stash
-p |void |sv_setpvf |SV* sv|const char* pat|...
+fp |void |sv_setpvf |SV* sv|const char* pat|...
p |void |sv_vsetpvf |SV* sv|const char* pat|va_list* args
p |void |sv_setiv |SV* sv|IV num
p |void |sv_setpviv |SV* sv|IV num
@​@​ -1756,9 +1764,9 @​@​
p |void |vivify_ref |SV* sv|U32 to_what
p |I32 |wait4pid |Pid_t pid|int* statusp|int flags
p |void |report_uninit
-p |void |warn |const char* pat|...
+fp |void |warn |const char* pat|...
p |void |vwarn |const char* pat|va_list* args
-p |void |warner |U32 err|const char* pat|...
+fp |void |warner |U32 err|const char* pat|...
p |void |vwarner |U32 err|const char* pat|va_list* args
p |void |watch |char** addr
p |I32 |whichsig |char* sig
@​@​ -1788,12 +1796,12 @​@​
#endif
p |int |runops_standard
p |int |runops_debug
-p |void |sv_catpvf_mg |SV *sv|const char* pat|...
+fp |void |sv_catpvf_mg |SV *sv|const char* pat|...
p |void |sv_vcatpvf_mg |SV* sv|const char* pat|va_list* args
p |void |sv_catpv_mg |SV *sv|const char *ptr
p |void |sv_catpvn_mg |SV *sv|const char *ptr|STRLEN len
p |void |sv_catsv_mg |SV *dstr|SV *sstr
-p |void |sv_setpvf_mg |SV *sv|const char* pat|...
+fp |void |sv_setpvf_mg |SV *sv|const char* pat|...
p |void |sv_vsetpvf_mg |SV* sv|const char* pat|va_list* args
p |void |sv_setiv_mg |SV *sv|IV i
p |void |sv_setpviv_mg |SV *sv|IV iv
@​@​ -1806,7 +1814,7 @​@​
p |MGVTBL*|get_vtbl |int vtbl_id
p |char* |pv_display |SV *sv|char *pv|STRLEN cur|STRLEN len \
  |STRLEN pvlim
-p |void |dump_indent |I32 level|PerlIO *file|const char* pat|...
+fp |void |dump_indent |I32 level|PerlIO *file|const char* pat|...
p |void |dump_vindent |I32 level|PerlIO *file|const char* pat \
  |va_list *args
p |void |do_gv_dump |I32 level|PerlIO *file|char *name|GV *sv
--- gv.c 1999/12/17 10​:14​:41 1.1
+++ gv.c 1999/12/17 11​:57​:11 1.2
@​@​ -1365,7 +1365,7 @​@​
  if (amtp && amtp->fallback >= AMGfallYES) {
  DEBUG_o( Perl_deb(aTHX_ "%s", SvPVX(msg)) );
  } else {
- Perl_croak(aTHX_ "%_", msg);
+ Perl_croak(aTHX_ "%"SVf, msg);
  }
  return NULL;
  }
--- op.c 1999/12/16 14​:23​:57 1.1
+++ op.c 1999/12/17 11​:57​:11 1.3
@​@​ -4152,7 +4152,7 @​@​
  gv_efullname3(name = sv_newmortal(), gv, Nullch);
  sv_setpv(msg, "Prototype mismatch​:");
  if (name)
- Perl_sv_catpvf(aTHX_ msg, " sub %_", name);
+ Perl_sv_catpvf(aTHX_ msg, " sub %"SVf, name);
  if (SvPOK(cv))
  Perl_sv_catpvf(aTHX_ msg, " (%s)", SvPVX(cv));
  sv_catpv(msg, " vs ");
@​@​ -4160,7 +4160,7 @​@​
  Perl_sv_catpvf(aTHX_ msg, "(%s)", p);
  else
  sv_catpv(msg, "none");
- Perl_warner(aTHX_ WARN_UNSAFE, "%_", msg);
+ Perl_warner(aTHX_ WARN_UNSAFE, "%"SVf, msg);
  }
}

--- perl.c 1999/12/17 10​:14​:41 1.1
+++ perl.c 1999/12/17 11​:57​:11 1.2
@​@​ -2159,7 +2159,7 @​@​
  -e \"/^#[ ]*undef[ ]/b\" \
  -e \"/^#[ ]*endif/b\" \
  -e \"s/^#.*//\" \
- %s | %_ -C %_ %s",
+ %s | %"SVf" -C %"SVf" %s",
  (PL_doextract ? "-e \"1,/^#/d\n\"" : ""),
#else
# ifdef __OPEN_VM
@​@​ -2175,7 +2175,7 @​@​
  -e '/^#[ ]*undef[ ]/b' \
  -e '/^#[ ]*endif/b' \
  -e 's/^[ ]*#.*//' \
- %s | %_ %_ %s",
+ %s | %"SVf" %"SVf" %s",
# else
  Perl_sv_setpvf(aTHX_ cmd, "\
%s %s -e '/^[^#]/b' \
@​@​ -2189,7 +2189,7 @​@​
  -e '/^#[ ]*undef[ ]/b' \
  -e '/^#[ ]*endif/b' \
  -e 's/^[ ]*#.*//' \
- %s | %_ -C %_ %s",
+ %s | %"SVf" -C %"SVf" %s",
# endif
#ifdef LOC_SED
  LOC_SED,
--- perl.h 1999/12/16 16​:29​:58 1.1
+++ perl.h 1999/12/17 11​:57​:11 1.2
@​@​ -171,6 +171,10 @​@​
# define dTHX dTHXa(PERL_GET_THX)
# define pTHX_ pTHX,
# define aTHX_ aTHX,
+# define pTHX_1 2
+# define pTHX_2 3
+# define pTHX_3 4
+# define pTHX_4 5
#endif

#define STATIC static
@​@​ -203,6 +207,10 @​@​
# define aTHX_
# define dTHXa(a) dNOOP
# define dTHX dNOOP
+# define pTHX_1 1
+# define pTHX_2 2
+# define pTHX_3 3
+# define pTHX_4 4
#endif

#ifndef pTHXo
@​@​ -3101,3 +3109,11 @​@​
#undef PERL_PATCHLEVEL_H_IMPLICIT

#endif /* Include guard */
+
+#ifndef SVf
+# ifdef CHECK_FORMAT
+# define SVf "p"
+# else
+# define SVf "_"
+# endif
+#endif
--- pp_ctl.c 1999/12/17 10​:14​:41 1.1
+++ pp_ctl.c 1999/12/17 11​:57​:11 1.2
@​@​ -1296,7 +1296,7 @​@​
  else if (PL_errors)
  sv_catsv(PL_errors, err);
  else
- Perl_warn(aTHX_ "%_", err);
+ Perl_warn(aTHX_ "%"SVf, err);
  ++PL_error_count;
}

--- pp_sys.c 1999/12/17 10​:14​:41 1.1
+++ pp_sys.c 1999/12/17 11​:57​:11 1.2
@​@​ -442,7 +442,7 @​@​
  if (!tmps || !len)
  tmpsv = sv_2mortal(newSVpvn("Warning​: something's wrong", 26));

- Perl_warn(aTHX_ "%_", tmpsv);
+ Perl_warn(aTHX_ "%"SVf, tmpsv);
  RETSETYES;
}

@​@​ -500,7 +500,7 @​@​
  if (!tmps || !len)
  tmpsv = sv_2mortal(newSVpvn("Died", 4));

- DIE(aTHX_ "%_", tmpsv);
+ DIE(aTHX_ "%"SVf, tmpsv);
}

/* I/O. */
--- regcomp.c 1999/12/16 14​:23​:57 1.1
+++ regcomp.c 1999/12/17 11​:57​:11 1.2
@​@​ -1590,7 +1590,7 @​@​
  r->reganch &= ~ROPT_SKIP; /* Used in find_byclass(). */
  DEBUG_r((sv = sv_newmortal(),
  regprop(sv, (regnode*)data.start_class),
- PerlIO_printf(Perl_debug_log, "synthetic stclass.\n",
+ PerlIO_printf(Perl_debug_log, "synthetic stclass `%s'.\n",
  SvPVX(sv))));
  }

@​@​ -1639,7 +1639,7 @​@​
  r->reganch &= ~ROPT_SKIP; /* Used in find_byclass(). */
  DEBUG_r((sv = sv_newmortal(),
  regprop(sv, (regnode*)data.start_class),
- PerlIO_printf(Perl_debug_log, "synthetic stclass.\n",
+ PerlIO_printf(Perl_debug_log, "synthetic stclass `%s'.\n",
  SvPVX(sv))));
  }
  }
--- sv.c 1999/12/17 10​:14​:41 1.1
+++ sv.c 1999/12/17 11​:57​:11 1.2
@​@​ -5559,7 +5559,7 @​@​
  (UV)c & 0xFF);
  } else
  sv_catpv(msg, "end of string");
- Perl_warner(aTHX_ WARN_PRINTF, "%_", msg); /* yes, this is reentrant */
+ Perl_warner(aTHX_ WARN_PRINTF, "%"SVf, msg); /* yes, this is reentrant */
  }

  /* output mangled stuff ... */
--- toke.c 1999/12/17 10​:14​:41 1.1
+++ toke.c 1999/12/17 11​:57​:11 1.2
@​@​ -6997,7 +6997,7 @​@​
  PL_multi_end = 0;
  }
  if (PL_in_eval & EVAL_WARNONLY)
- Perl_warn(aTHX_ "%_", msg);
+ Perl_warn(aTHX_ "%"SVf, msg);
  else
  qerror(msg);
  if (PL_error_count >= 10)

--
Robin Barker | Eail​: Robin.Barker@​npl.co.uk
CISE, Building 10, | Phone​: +44 (0) 20 8943 7090
National Physical Laboratory, | Fax​: +44 (0) 20 8977 7091
Teddington, Middlesex, UK. TW11 OLW | WWW​: http​://www.npl.co.uk

@p5pRT
Copy link
Author

p5pRT commented Dec 17, 1999

From @gsar

On Fri, 17 Dec 1999 13​:31​:18 GMT, Robin Barker wrote​:

The attached patch adds code for checking printf formats using -DCHECK_FORMAT​:
- it adds attributes for format checking in proto.h (via embed.h)

Thanks.

- it replaces "%_" by "%"SVf which become "%p" with -DCHECK_FORMAT

That changes semantics. The %_ type prints the contents of the SV
while %p prints the address.

- without -DCHECK_FORMAT the patch should be effectively NOOP

Applying the patch, configuring with -Dccflags="-Wformat -DCHECK_FORMAT",
and <make>ing gives the following. <make test> fails some tests because
"%p" does not give the same results as "%_"!

Naturally, they're not the same.

Sarathy
gsar@​ActiveState.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant