diff --git a/cobc/ChangeLog b/cobc/ChangeLog index 8c5853b8e..03b6b65b0 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -52,6 +52,16 @@ * pplex.l (cb_text_list): prevent duplicates +2024-08-30 Ammar Almorsi + + BUG #961: Nested Elements Mishandled Despite 'with attributes' Specification + * tree.c (set_ml_attrs_and_children): Enhanced the function to handle + the case where a child has attributes + * codegen.c (output_ml_suppress_checks): Modified the starting point + to start from the last attribute if present + * codegen.c (get_prev_ml_tree_entry): Removed the fallback case to + prevent infinite loops + 2024-08-28 David Declerck * tree.c (char_to_precedence_idx, get_char_type_description, valid_char_order): diff --git a/cobc/codegen.c b/cobc/codegen.c index c46d67f24..2710761f8 100644 --- a/cobc/codegen.c +++ b/cobc/codegen.c @@ -3485,8 +3485,6 @@ get_prev_ml_tree_entry (const struct cb_ml_generate_tree * const s) } else { return s->prev_sibling; } - } else if (s->attrs) { - return get_last_attr (s); } else if (s->parent) { return s->parent; } else { @@ -8342,14 +8340,14 @@ output_ml_suppress_checks (struct cb_ml_suppress_checks * const suppress_checks) struct cb_ml_generate_tree *tree; /* - To resolve dependency problems, start from last child of last element. + To resolve dependency problems, start from last child/attribute of last element. */ - if (orig_tree->children) { + tree = orig_tree; + if (tree->children) { tree = get_last_child (orig_tree); - } else if (orig_tree->attrs) { + } + if (tree->attrs) { tree = get_last_attr (orig_tree); - } else { - tree = orig_tree; } for (;;) { diff --git a/cobc/tree.c b/cobc/tree.c index 0e2f9bb18..9ae64d219 100644 --- a/cobc/tree.c +++ b/cobc/tree.c @@ -1300,10 +1300,18 @@ set_ml_attrs_and_children (struct cb_field *record, const int children_are_attrs continue; } - child_tree_or_null = cb_build_ml_tree (child, 0, - children_are_attrs, - name_list, type_list, - suppress_list); + if (child->children) { + child_tree_or_null = cb_build_ml_tree (child, children_are_attrs, + 0, + name_list, type_list, + suppress_list); + } else { + child_tree_or_null = cb_build_ml_tree (child, 0, + children_are_attrs, + name_list, type_list, + suppress_list); + } + if (!child_tree_or_null) { continue; } diff --git a/tests/testsuite.src/run_ml.at b/tests/testsuite.src/run_ml.at index 2b94f4bb2..5fa66f69a 100644 --- a/tests/testsuite.src/run_ml.at +++ b/tests/testsuite.src/run_ml.at @@ -124,6 +124,40 @@ AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [], []) AT_CLEANUP +AT_SETUP([XML GENERATE WITH ATTRIBUTES]) +AT_KEYWORDS([extensions]) + +AT_SKIP_IF([test "$COB_HAS_XML2" = "no"]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 out PIC X(200). + 01 NSTD. + 05 ATT1 pic x(4) value "ATT1". + 05 CHLD1. + 10 NSTD_ATT1 pic x(9) value "NSTD_ATT1". + 10 NSTD_ATT2 pic x(9) value "NSTD_ATT2". + 05 ATT2 pic x(4) value "ATT2". + + PROCEDURE DIVISION. + XML GENERATE out FROM NSTD WITH ATTRIBUTES + IF out <> ''- + '' + DISPLAY 'Test 11 failed: ' FUNCTION TRIM (out) + END-IF + . +]) + +AT_CHECK([$COMPILE -fnot-reserved=ID prog.cob], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [], []) +AT_CLEANUP + + AT_SETUP([XML GENERATE SUPPRESS]) AT_KEYWORDS([extensions])