Our COBOL V4.2 compiler has NUMPROC(MIG) specified. For V5.2 and now V6.2 (and 6.3) we have NUMPROC(NOPFD) and ZONEDATA(MIG). Yesterday a program was implemented with a minor change, but caused major havoc. The change itself was fine, but it looks like the behavior of the compiler changed between the last time the program was compiled and the current time. The code in question was checking for equality between a packed decimal field and a zoned decimal field. Unfortunately the zoned decimal field (for reasons TBD) contained only binary zeroes, rather than a valid zoned decimal value. The code generated by our current V6.2 compiler is as follows:
PACK 162(6,R13),1416(10,R9) # WS-UNPACKED-BRANCH-ACCT-
CP 6(10,R4),162(6,R13) # CHR-XREF-APPL-ACCT
JNE L0217
We don't have access to the previous version of V6.2, but we do still have V5.2 hanging around. Here is the code it generates:
MVC 166(10,R13),6(R4) # _VTS_1 CHR-XREF-APPL-ACCT
OI 175(,R13),X'0F' # _VTS_1
PACK 210(6,R13),1464(10,R8)
OI 215(,R13),X'0F' # _VTS_2
CP 166(10,R13),210(6,R13)
JNE L0216
And here is V4.2:
PACK 1112(6,13),3664(10,3) TS2=0 WS-UNPACKED-BRANCH-ACCT-NBR
CP 1198(10,2),1112(6,13) CHR-XREF-APPL-ACCT TS2=0
BC 7,1052(0,11) GN=33(002BEE)
So the behavior of V6.2 is now (generally) the same as V4.2, but different from V5.2 (and I assume the "older" V6.2).
As you can see, V6.2/4.2 simply packs the zoned decimal field and then compares the resulting packed decimal field to the other packed decimal field. The V5.2 version, which I am assuming was how V6.2 was behaving until a (fairly) recent update, does a "sign fixup" on both fields prior to the compare. Thus what was previously invalid data is fixed to be valid data prior to the compare operation, thus avoiding the data exception condition being generated.
We had a similar issue about a month ago so I knew pretty much immediately how to make a short term fix to resolve the issue. And that was to add a check to make sure the zoned decimal field is numeric before doing the actual compare. Of course the long-term fix is to make sure the zoned decimal field has a valid numeric value prior to doing the comparison.
It looks like the latest fixes for V6.2 and V6.3 have a new compiler option, INVDATA. It's described here:
https://www.ibm.com/support/pages/apar/PH31500.The APAR says that if you had NUMPROC(MIG) you should now use INVDATA(FORCENUMCMP,NOCLEANSIGN) (along with, I assume, NUMPROC(NOPFD)). This will give us the behavior shown above for V6.2 and V4.2. Would it be the case that we could specify INVDATA(FORCENUMCMP,CLEANSIGN) if we want to get the V5.2 behavior back? It seems like we might want to do this, even though it's different than V4.2 behavior, because we've already converted over 1000 programs to V5.2 or V6.2, and we'd prefer to avoid unexpected production abends for "previously working" V5.2 (and older V6.2) code.
On a related note, I'm wondering if it might make sense to still use INVDATA(FORCENUMCMP,NOCLEANSIGN) for development compiles, with INVDATA(FORCENUMCMP,CLEANSIGN) only for production. This way we could get data exceptions for bad data during development, but avoid them in production. So hopefully we would find and fix invalid data situations prior to going in to production, but also avoid being hit by data exception abends in production.
------------------------------
Frank Swarbrick
------------------------------