identification division. program-id. 'sub' data division. working-storage section. 01 hold-cred-score pic s9(3) comp-3. 88 valid-cred-score values 000 300 thru 699 998 999. linkage section. 01 parms. 05 cred-score pic 9(3). procedure division using parms. move cred-score to hold-cred-score display hold-cred-score if valid-cred-score display 'valid credit score' else display 'not a valid credit score' end-if goback. end program 'sub'.
When OPT(1) or OPT(2) is specified, the optimizer appears to not check hold-credit-score for the valid values but in fact, using some "interesting logic", appears to check cred-score instead.
This has caused a problem when cred-score is not a valid zoned decimal. In particular, it is x'0000F0'. I'm not really asking how to "fix" this program, as there are probably several ways. Or even leaving it as-is and fixing the data prior to the calling of this program. I don't know if this really APARable, since COBOL really makes no guarantee about how it handles invalid data in a zoned decimal (DISPLAY) numeric field. Just thought I'd "throw it out there" so see if anyone has any comments.
Related, I know that the ZONECHECK compiler option would catch the invalid data. Up to this point we have not been using it. And certainly (?) we don't want to use it for a final production compile. But I can't decide on a good "philosophy" as to when it should be used. As we migrate programs to COBOL 5 (or 6, once we start using it) we could use ZONECHECK and do an initial regression test. After fixing any cases where we are dealing with "bad data" we could stop using it (for that program). But this kind of assumes that new development won't introduce any new issues with zoned data. So do we just always do ZONECHECK for "development" compiles, and NOZONECHECK for production? What kind of performance hit would that be for programs running in dev with ZONECHECK?
If you are interested, the following is the relevant code generated at OPT(2).
000036: 003200 move cred-score to hold-cred-score 000300 4100 8038 000036 LA R0,56(,R8) # 000038: 003400 display hold-cred-score 000304 4110 D0A0 000038 LA R1,160(,R13) # _ArgumentList 000308 000036 SNAPSHOT STMT 000308 5820 8000 000036 L R2,0(,R8) # BLL_1 00030C F212 8038 2000 000036 PACK 56(2,R8),0(3,R2) # HOLD-CRED-SCORE CRED-SCORE 000312 D100 8039 3001 000036 MVN 57(1,R8),1(R3) # HOLD-CRED-SCORE _$CONSTANT_AREA 000318 000038 SNAPSHOT STMT 000318 D217 D0A0 3130 000038 MVC 160(24,R13),304(R3) # _$CONSTANT_AREA+304 00031E 58F0 30D8 000038 L R15,216(,R3) # _ACON 000322 5000 D0A8 000038 ST R0,168(,R13) # 000326 58C0 D084 000038 L R12,132(,R13) # _@CAA 00032A 0DEF 000038 BASR R14,R15 # Call "IGZXDSP" 00032C 1812 000038 LR R1,R2 000039: 003500 if valid-cred-score 00032E 000039 SNAPSHOT STMT 00032E 1700 000036 XR R0,R0 000330 BF07 1000 000036 ICM R0,X'7',0(,R1) # CRED-SCORE 000334 C00D FF00 00F0 000036 OILF R0,X'FF0000F0' 00033A C20D FFF0 F0F0 000039 CFI R0,X'FFF0F0F0' 000340 A784 0016 000039 JE L0005 000344 C20F FFF3 F0F0 000039 CLFI R0,X'FFF3F0F0' 00034A A744 0007 000039 JL L0006 00034E C20F FFF6 F9F9 000039 CLFI R0,X'FFF6F9F9' 000354 A7C4 000C 000039 JNH L0005 000358 000039 L0006: EQU * 000358 D501 8038 3148 000039 CLC 56(2,R8),328(R3) # HOLD-CRED-SCORE _$CONSTANT_AREA+328 00035E A784 0007 000039 JE L0005 000362 D501 8038 314A 000039 CLC 56(2,R8),330(R3) # HOLD-CRED-SCORE _$CONSTANT_AREA+330 000368 A764 000E 000039 JNE L0007 00036C 000039 L0005: EQU *
Shoot, this bulletin board really doesn't like COBOL source code. The line at offset 000330 above is really the following:
ICM R0,X'7',0(,R1) # CRED-SCORE
fswarbrick