diff options
author | David Mitchell <davem@iabyn.com> | 2015-09-09 13:02:40 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2015-10-02 11:18:17 +0100 |
commit | 73e8ff0004522621dfb42f01966853b51d5522a6 (patch) | |
tree | 1e2b70f790f84ab21c55ecfc85291511408af7ed /sv.c | |
parent | 0fa1f7e4e66a455cab6ccf1f9c49f2373c1ced80 (diff) | |
download | perl-73e8ff0004522621dfb42f01966853b51d5522a6.tar.gz |
fix some 32/64-bit compiler warnings
Some bits of code don't do well on a 32-bit system with 64-bit ints
(-Duse64bitint)
In particular:
_MEM_WRAP_NEEDS_RUNTIME_CHECK:
if sizeof(MEM_SIZE) > sizeof(n), then the shift count could be
negative
S_regmatch:
ln and n were two different sizes and signesses, so comparing them
warned. Since they were being mis-used as two convenient temporary
booleans anyway, just use temporary booleans instead.
Perl_sv_vcatpvfn_flags:
the test/assertion (IV)elen < 0 was (I think) being used to test for
signed/unsigned conversion wrap-around. elen is of type STRLEN which
is a pointer-based type, so can be 32-bit while IV is 64-bit. Instead
compare it to half the maximum value of a STRLEN var to see if it may
have wrapped.
Diffstat (limited to 'sv.c')
-rw-r--r-- | sv.c | 10 |
1 files changed, 6 insertions, 4 deletions
@@ -11444,9 +11444,10 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p is safe. */ is_utf8 = (bool)va_arg(*args, int); elen = va_arg(*args, UV); - if ((IV)elen < 0) { - /* check if utf8 length is larger than 0 when cast to IV */ - assert( (IV)elen >= 0 ); /* in DEBUGGING build we want to crash */ + /* if utf8 length is larger than 0x7ffff..., then it might + * have been a signed value that wrapped */ + if (elen > ((~(STRLEN)0) >> 1)) { + assert(0); /* in DEBUGGING build we want to crash */ elen= 0; /* otherwise we want to treat this as an empty string */ } eptr = va_arg(*args, char *); @@ -12690,7 +12691,8 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p } } - assert((IV)elen >= 0); /* here zero elen is fine */ + /* signed value that's wrapped? */ + assert(elen <= ((~(STRLEN)0) >> 1)); have = esignlen + zeros + elen; if (have < zeros) croak_memory_wrap(); |