From: Jarkko Hietaniemi Date: Tue, 22 Dec 1998 08:39:30 +0000 (+0000) Subject: Slight recoding of util.c:repeatcpy() to circumnavigate X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5926133d519625e5c6cc80fa9f5881300623dca1;p=p5sagit%2Fp5-mst-13.2.git Slight recoding of util.c:repeatcpy() to circumnavigate a Digital C compiler optimizer bug that broke the 'x' operator under certain circumstances. See t/op/repeat.t test #20 for graphic details. Reported in From: Gisle Aas To: Mark Martinec Cc: ach@xray.mpe.mpg.de, cpan-testers@perl.org, perl5-porters@perl.org Subject: Re: Digest-MD5-2.00 test fails on DEC Alpha - a patch Date: 18 Dec 1998 14:27:40 +0100 Message-ID: and discussed further in the thread From: Jarkko Hietaniemi To: Gisle Aas Cc: Mark Martinec , ach@xray.mpe.mpg.de, cpan-testers@perl.org, perl5-porters@perl.org Subject: x operator broken in DEC Alpha for 8-bit characters (Re: Digest-MD5-2.00 test fails on DEC Alpha - a patch) Date: Fri, 18 Dec 1998 16:18:37 +0200 (EET) Message-ID: <13946.25661.193449.138023@alpha.hut.fi> p4raw-id: //depot/cfgperl@2498 --- diff --git a/t/op/repeat.t b/t/op/repeat.t index 54fa590..f935bf1 100755 --- a/t/op/repeat.t +++ b/t/op/repeat.t @@ -2,7 +2,7 @@ # $RCSfile: repeat.t,v $$Revision: 4.1 $$Date: 92/08/07 18:28:21 $ -print "1..19\n"; +print "1..20\n"; # compile time @@ -40,3 +40,54 @@ print join(':', () x 4) eq '' ? "ok 16\n" : "not ok 16\n"; print join(':', (9) x 4) eq '9:9:9:9' ? "ok 17\n" : "not ok 17\n"; print join(':', (9,9) x 4) eq '9:9:9:9:9:9:9:9' ? "ok 18\n" : "not ok 18\n"; print join('', (split(//,"123")) x 2) eq '123123' ? "ok 19\n" : "not ok 19\n"; + +# +# The test #20 is actually testing for Digital C compiler optimizer bug. +# +# Dec C versions 5.* and 6.0 (used in Digital UNIX and VMS) used +# to produce (as of December 1998) broken code for util.c:repeatcpy() +# (a utility function for the 'x' operator) in the case *all* these +# four conditions held: +# +# (1) len == 1 +# (2) "from" had the 8th bit on in its single character +# (3) count > 7 (the 'x' count > 16) +# (4) the highest optimization level was used in compilation +# (which is the default when compiling Perl) +# +# The bug looked like this (. being the eight-bit character and ? being \xff): +# +# 16 ................ +# 17 .........???????. +# 18 .........???????.. +# 19 .........???????... +# 20 .........???????.... +# 21 .........???????..... +# 22 .........???????...... +# 23 .........???????....... +# 24 .........???????.??????? +# 25 .........???????.???????. +# +# The bug could be (obscurely) avoided by changing "from" to +# be an unsigned char pointer. +# +# The bug was triggered in the "if (len == 1)" branch. The fix +# was to introduce a new temporary variable. In diff -u format: +# +# register char *frombase = from; +# +# if (len == 1) { +#- todo = *from; +#+ register char c = *from; +# while (count-- > 0) +#- *to++ = todo; +#+ *to++ = c; +# return; +# } +# +# This obscure bug was not found by the then test suite but instead +# by Mark.Martinec@nsc.ijs.si while trying to install Digest-MD5-2.00. +# +# jhi@iki.fi +# +print "\xdd" x 24 eq "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" ? "ok 20\n" : "not ok 20\n"; diff --git a/util.c b/util.c index 7d6c184..cc4591e 100644 --- a/util.c +++ b/util.c @@ -2279,9 +2279,9 @@ repeatcpy(register char *to, register char *from, I32 len, register I32 count) register char *frombase = from; if (len == 1) { - todo = *from; + register char c = *from; while (count-- > 0) - *to++ = todo; + *to++ = c; return; } while (count-- > 0) {