Skip to content

Conversation

@ddeclerck
Copy link
Collaborator

This adds a test for COMP-5 binary size in presence of P.

@GitMensch
Copy link
Collaborator

That's good - let's expand this by adding the non P versions with expected same size and one run for each of the -fbinary-size options, then we have all things related to this in one single test run with different expected results.

Thanks again!

@ddeclerck
Copy link
Collaborator Author

Updated.

I'm a bit surprised by the results for -fbinary-size=2-4-8 though ; shouldn't V9(1) be two bytes with this setting ?

@GitMensch
Copy link
Collaborator

yes, so the testcase uncovered a bug (that trunk may not have any more...)

@ddeclerck
Copy link
Collaborator Author

Also present in GC4.

Apparently this is caused by this (field.c:compute_binary_size):

	case CB_BINARY_SIZE_2_4_8:
		if (f->flag_real_binary && size <= 2) {
			f->size = 1;
		} else {
			f->size = ((size <= 4) ? 2 :
				   (size <= 9) ? 4 : (size <= 18) ? 8 : 16);
		}

And this (field.c:validate_elementary_item):

	case CB_USAGE_COMP_5:
		f->flag_real_binary = 1;

I'd say it suffices to not set flag_real_binary when we have CB_USAGE_COMP_5 ?

But I'm also wondering, when flag_real_binary is set, why do we need to take the binary-size option into account ?

@ddeclerck
Copy link
Collaborator Author

I'd say it suffices to not set flag_real_binary when we have CB_USAGE_COMP_5 ?

But I'm also wondering, when flag_real_binary is set, why do we need to take the binary-size option into account ?

Actually nope, I understand we must keep flag_real_binary = 1 in validate_elementary_item.

However removing the specific case for f->flag_real_binary && size <= 2 in compute_binary_size fixes the problem, without breaking anything in the testsuite. But is it the right thing to do, @GitMensch ? Was this specific case added for a reason (not covered by the testsuite) ?

@GitMensch
Copy link
Collaborator

GitMensch commented Oct 29, 2024

Rechecked (that complete check and specification below took more than two hours :-/ maybe I start to get old...): for 2-4-8 we should indeed never have a size of 1 (note: that setting is the GC3 implementation of MF's IBMCOMP directive, included in IBM + RM, but not in BS2000 [which does document 2-4-8-16 in its own documentation, a setting that is actually what our 2-4-8 means - we possibly should adjust the names in GC4...]).
Also checked Realia docs - the current 2-4-8 we have there is correct.

Attention: Per GCOS docs the right binary-size option would be 2-4-6-8, which is not the case (it is currently 2-4-8) - you may want to add that configuration option and setting!

Also: acu-strict.conf currently has binary-size: 1-2-4-8 # not verified yet - according to their docs (rule 8+9) that must be changed to 2-4-8-12-16 - if you add the GCOS one, please add this as well, if not please adjust it to the more correct 2-4-8.

So I've gone through the annotate/blame to check where the changes come from. For field.c that's May 2007, history:r2575

  • field.c : BINARY-CHAR is always one byte regardless of -std=

That should obviously be the case and we should have a testcase for this...
But this seems to be not the case as you've said nothing breaks. Can you please add another test that verifies the BINARY-... types being the correct size [testing in COBOL with IF BYTE-LENGTH(var-char) <> 1 DISPLAY "BAD BINARY-CHAR"., then compile and run once with -fbinary-size=1--8 and once with -fbinary-size=2-4-8]).

And this case was, back then, totally correct, which should answer your question.

The real issue is the addition of the flag_real_binary to COMP-5, which is relatively new - from January 2017 code:r1372, merged in by me with r1423 in February 2017.

  • field.c: Correction so that COB_FLAG_REAL_BINARY will be set on for COMP-5

This end result is correct (it is mostly about binary truncation instead of arithmetic one) but that actual change has an effect on the size generation as we found out - that it should not have for COMP-5! Even tree.h flag_real_binary tells us that...

To fix it (you know, when you work on the test cases I can focus on the code...)
adjust field.c:

 	case CB_USAGE_COMP_5:
-		f->flag_real_binary = 1;

and codegen.c:

-				if (f->flag_real_binary) {
+				if (f->flag_real_binary
+				 || f->usage == CB_USAGE_COMP_5) {
 					flags |= COB_FLAG_REAL_BINARY;
 				}
 				if (f->flag_is_pointer) {
 					flags |= COB_FLAG_IS_POINTER;
 				}
-				if (cb_binary_truncate &&
- 				    f->usage == CB_USAGE_BINARY &&
- 				    !f->flag_real_binary) {
+				if (cb_binary_truncate
+				 && f->usage == CB_USAGE_BINARY
+ 				 && !f->flag_real_binary) {
 					flags |= COB_FLAG_BINARY_TRUNC;
 					flags |= COB_FLAG_BINARY_TRUNC;
 				}
 
-				if (type == COB_TYPE_NUMERIC_BINARY
-				 && f->usage == CB_USAGE_INDEX) {
-					flags |= COB_FLAG_REAL_BINARY;
-					type = COB_TYPE_NUMERIC_COMP5;
-				} else
-				if (type == COB_TYPE_NUMERIC_BINARY
-				 && (f->flag_binary_swap || f->flag_real_binary)
-				 && (f->flag_indexed_by || f->index_type || f->flag_internal_register)) {
-					type = COB_TYPE_NUMERIC_COMP5;
+				if (type == COB_TYPE_NUMERIC_BINARY) {
+					if (f->usage == CB_USAGE_INDEX) {
+						flags |= COB_FLAG_REAL_BINARY;
+						type = COB_TYPE_NUMERIC_COMP5;
+					} else
+					if ((f->flag_binary_swap || f->flag_real_binary)
+					 && (f->flag_indexed_by || f->index_type || f->flag_internal_register)) {
+						type = COB_TYPE_NUMERIC_COMP5;
+					}
 				}

and of course Changelog:

2024-10-29  Simon Sobisch <[email protected]>

	* field.c (validate_elementary_item): only set flag_real_binary for
	  BINARY-CHAR/BINARY-SHORT/BINARY-LONG/BINARY-DOUBLE
	* codegenc (output_attr): generate COB_FLAG_REAL_BINARY also for COMP-5

and NEWS

+** #NNN: dialects without support of single byte binary data
+   will now generate at least 2 bytes of storage for COMP-5 elements; this
+   applies to all non-standard dialects but GnuCOBOL (default) and Micro Focus;
+   that changes the group length of records containing elements with less than
+   3 digits and also passes different sizes via CALL, which may need program
+   adjustments.
+
+** -std=acu / -std=acu-strict now generate BINARY and COMP-5 with at least
+   2 bytes of storage; the comment for #NNN above applies; if you want
+   to still use the sizes used since GnuCOBOL 2.2 with those dialects:
+   add -fbinary-size=1-2-4-8 to your compile options
+
 * Important Bugfixes

Which I think should both the existing testcases, the one you've added and the one new for BINARY-CHAR and friends.

If you prefer, I could also do this commit upstream.

@ddeclerck ddeclerck force-pushed the comp5_test branch 2 times, most recently from c99f785 to 63c7630 Compare October 30, 2024 10:04
@ddeclerck
Copy link
Collaborator Author

Attention: Per GCOS docs the right binary-size option would be 2-4-6-8, which is not the case (it is currently 2-4-8) - you may want to add that configuration option and setting!

Yeah, that's definately something we should consider (back then, we just chosed what was the "closest").

That should obviously be the case and we should have a testcase for this... But this seems to be not the case as you've said nothing breaks. Can you please add another test that verifies the BINARY-... types being the correct size [testing in COBOL with IF BYTE-LENGTH(var-char) <> 1 DISPLAY "BAD BINARY-CHAR"., then compile and run once with -fbinary-size=1--8 and once with -fbinary-size=2-4-8]).

Tests added ;)

And this case was, back then, totally correct, which should answer your question.

Yup, reading the code a bit more, I get why this was made this way.

Which I think should both the existing testcases, the one you've added and the one new for BINARY-CHAR and friends.

Yes, that seems to fix everything.

If you prefer, I could also do this commit upstream.

Well, I included your changes in this PR, so I can take care of that.

Copy link
Collaborator

@GitMensch GitMensch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please include the last change as well: config/acu-strict.conf (+Changelog)

-binary-size:			1-2-4-8	# not verified yet
+binary-size:			2-4-8	# TODO: add 2-4-8-12-16

@ddeclerck
Copy link
Collaborator Author

Done.

Just realized I created the SVN ticket using a very old personal account of mine instead of my new "profesional" account - don't know if this can be changed...

@GitMensch
Copy link
Collaborator

GitMensch commented Oct 31, 2024

The creator change would need an export, adjustment and re-import, so there would have to be a very convincing reason to do so. But I've adjusted the text and assigned the ticket to your new account.

BTW: congrats for this nice issue number :-)

@ddeclerck
Copy link
Collaborator Author

The creator change would need an export, adjustment and re-import, so there would have to be a very convincing reason to do so. But I've adjusted the text and assigned the ticket to your new account.

Alright.

BTW: congrats for this nice issue number :-)

Yeah, do I get a prize ? 😉

So, is this PR "ready for SVN" ?

@GitMensch
Copy link
Collaborator

GitMensch commented Oct 31, 2024 via email

@ddeclerck
Copy link
Collaborator Author

I've started doc + testsuite adjustments, with the later resulting in realizing about a missing feature... If that's fine with you I'd do the upstream commit afterwards.

Alright, I leave it to you ;)

@ddeclerck
Copy link
Collaborator Author

Any news about this one ?

@ddeclerck
Copy link
Collaborator Author

I've started doc + testsuite adjustments, with the later resulting in realizing about a missing feature... If that's fine with you I'd do the upstream commit afterwards.

Not sure if those adjustments have been made, but apparently the contents of this PR has not been integrated to 3.x yet. Shall I upstream it to SVN ? (@GitMensch )

@ddeclerck
Copy link
Collaborator Author

Friendly ping, @GitMensch ;)

@rbowler
Copy link

rbowler commented Oct 13, 2025

Hi @GitMensch @ddeclerck any progress on this merge? The only conflicts are in cobc/ChangeLog and config/ChangeLog and these are easily resolved. It does fix the problem of PIC 9 COMP-5 being the wrong size (bug 1000), while still allowing BINARY-CHAR to be a 1-byte field, and it'd be nice if this bugfix could be merged before #248

@rbowler
Copy link

rbowler commented Oct 13, 2025

Sorry, hold that last comment. I discovered a problem with this fix. When compiling with -fbinary-size=2-4-8 -ftrunc these statements all produce: warning: value size exceeds data size [-Wothers]:

01  X-P5   PIC 9(2) COMP-5        VALUE 234.
01  X-P6   PIC 9(4) COMP-5        VALUE 23456.
01  X-P7   PIC 9(8) COMP-5        VALUE 2345678901.
01  X-P8   PIC 9(18) COMP-5       VALUE 2345678901234567891.

These should all be allowed because the idea of COMP-5 (on the mainframe at least, I don't know about MicroFocus) is that the values are limited by the size of the data item and not the number of 9's in the PIC, regardless of the TRUNC/NOTRUNC setting, unlike COMP which is affected by TRUNC/NOTRUNC.
So far as I can see this is what the f->flag_real_binary means in GnuCOBOL, and I think the problem is because the fix has delayed the setting of this flag for COMP-5 until code generation. The original problem was that field.c tries to distinguish between BINARY-CHAR and PIC 9 COMP, and currently it does this by testing the f->flag_real_binary flag, which inadvertently catches PIC 9 COMP-5 and so treats it as a 1-byte field.

@rbowler
Copy link

rbowler commented Oct 13, 2025

@ddeclerck @GitMensch This is the fix that I suggest:

  1. Revert the changes to field.c and codegen.c made by commit e766efe so that f->flag_real_binary will still be set for CB_USAGE_COMP_5
  2. Add new bitflag flag_binary_char in the cb_field structure in tree.h
  3. In field.c::validate_elementary_item() set f->flag_binary_char = 1 for cases CB_USAGE_SIGNED_CHAR and CB_USAGE_UNSIGNED_CHAR in addition to setting f->flag_real_binary
  4. In field.c::compute_binary_size() replace
    if (f->flag_real_binary && size <= 2) {
    by
    if (f->flag_binary_char) {

This does pass the tests "Fixed BINARY size" and "COMP-5 binary size" added by this branch. It also compiles the above code snippet PIC 9(2) COMP-5 VALUE 234. etc without warnings.

Attached patch file comp5-binary-size.patch

@GitMensch
Copy link
Collaborator

GitMensch commented Oct 13, 2025 via email

@rbowler
Copy link

rbowler commented Oct 20, 2025

rbowler:comp5_test is a branch based upon ddeclerck:comp5_test. It contains the suggested fix above plus an additional test case (COMP-5 binary values) which tests COMP-5 values which exceed the PIC but are within the binary size. If you merge it into this branch it resolves the issue with VALUE clauses that I mentioned above.

@ddeclerck
Copy link
Collaborator Author

@GitMensch What is your take on this ?

@GitMensch
Copy link
Collaborator

I need some more time to inspect this and the linked PR from @rbowler, but always keen to get comments from @ddeclerck as well :-)

@ddeclerck
Copy link
Collaborator Author

I need some more time to inspect this and the linked PR from @rbowler, but always keen to get comments from @ddeclerck as well :-)

I don't really have anything to add ; I thought that PR was already ready for merge; cf your earlier comment:

I've started doc + testsuite adjustments, with the later resulting in realizing about a missing feature... If that's fine with you I'd do the upstream commit afterwards.

@GitMensch GitMensch changed the base branch from gcos4gnucobol-3.x to gitside-gnucobol-3.x December 16, 2025 06:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants