Skip to content

Commit 6171195

Browse files
Detect duplicate labels (#774)
* fix: detect duplicate labels in a single section * wip: wip * wip: wip * test: fix tests for duplicate labels * wip: wip * fix: improve cb_validate_labels
1 parent ed0193c commit 6171195

4 files changed

Lines changed: 126 additions & 11 deletions

File tree

cobj/cobj.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,14 @@ static int process_translate(struct filename *fn) {
17791779
if (ret) {
17801780
return ret;
17811781
}
1782+
1783+
/* Validate duplicate labels in the same section */
1784+
for (q = current_program; q; q = q->next_program) {
1785+
if (cb_validate_labels(q)) {
1786+
return -1;
1787+
}
1788+
}
1789+
17821790
if (cb_flag_syntax_only || current_program->entry_list == NULL) {
17831791
return 0;
17841792
}

cobj/tree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,6 +1500,7 @@ extern void cb_validate_program_environment(struct cb_program *prog);
15001500
extern void cb_validate_program_data(struct cb_program *prog);
15011501
extern void cb_validate_program_body(struct cb_program *prog);
15021502
extern void cb_validate_indexed_file_key(const struct cb_file *f);
1503+
extern int cb_validate_labels(struct cb_program *prog);
15031504

15041505
extern cb_tree cb_build_expr(cb_tree list);
15051506
extern cb_tree cb_build_cond(cb_tree x);

cobj/typeck.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,51 @@ void cb_validate_program_body(struct cb_program *prog) {
14831483
}
14841484
}
14851485

1486+
int cb_validate_labels(struct cb_program *prog) {
1487+
cb_tree l1, l2;
1488+
int duplicate_count = 0;
1489+
1490+
for (l1 = prog->exec_list; l1; l1 = CB_CHAIN(l1)) {
1491+
cb_tree x1 = CB_VALUE(l1);
1492+
if (!CB_LABEL_P(x1)) {
1493+
continue;
1494+
}
1495+
struct cb_label *label1 = CB_LABEL(x1);
1496+
if (label1->is_section) {
1497+
continue;
1498+
}
1499+
1500+
for (l2 = CB_CHAIN(l1); l2; l2 = CB_CHAIN(l2)) {
1501+
cb_tree x2 = CB_VALUE(l2);
1502+
if (!CB_LABEL_P(x2)) {
1503+
continue;
1504+
}
1505+
struct cb_label *label2 = CB_LABEL(x2);
1506+
if (label2->is_section) {
1507+
break;
1508+
}
1509+
1510+
if (label1->section != label2->section) {
1511+
break;
1512+
}
1513+
1514+
if (strcmp((const char *)label1->name, (const char *)label2->name) == 0) {
1515+
if (!label2->section || !label2->section->name ||
1516+
strcmp((char *)label2->section->name, "MAIN SECTION") == 0) {
1517+
cb_error_x(x2, _("Duplicate paragraph '%s' in the default section"),
1518+
label2->name);
1519+
} else {
1520+
cb_error_x(x2, _("Duplicate paragraph '%s' in section '%s'"),
1521+
label2->name, label2->section->name);
1522+
}
1523+
cb_error_x(x1, _("'%s' previously defined here"), label1->name);
1524+
duplicate_count++;
1525+
}
1526+
}
1527+
}
1528+
return duplicate_count;
1529+
}
1530+
14861531
/*
14871532
* Expressions
14881533
*/

tests/syntax.src/definition.at

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -501,24 +501,85 @@ AT_CLEANUP
501501

502502
AT_SETUP([Redefinition of paragraph names])
503503

504-
AT_DATA([prog.cob], [
504+
AT_DATA([prog1.cob], [
505505
IDENTIFICATION DIVISION.
506-
PROGRAM-ID. prog.
506+
PROGRAM-ID. prog1.
507507
PROCEDURE DIVISION.
508+
*No Label
508509
L.
510+
*No Label
509511
L.
510512
STOP RUN.
511513
])
512514

513-
AT_CHECK([${COMPILE_ONLY} prog.cob], [0], ,
514-
[])
515-
516-
## Change when we DON'T allow this
517-
## AT_CHECK([${COMPILE_ONLY} prog.cob], [1], ,
518-
## [prog.cob: In paragraph 'L':
519-
## prog.cob:6: Error: redefinition of 'L'
520-
## prog.cob:5: Error: 'L' previously defined here
521-
## ])
515+
AT_DATA([prog2.cob], [
516+
IDENTIFICATION DIVISION.
517+
PROGRAM-ID. prog2.
518+
PROCEDURE DIVISION.
519+
SECTION-A SECTION.
520+
L.
521+
*No Label
522+
L.
523+
STOP RUN.
524+
])
525+
526+
AT_DATA([prog3.cob], [
527+
IDENTIFICATION DIVISION.
528+
PROGRAM-ID. prog3.
529+
PROCEDURE DIVISION.
530+
SECTION-A SECTION.
531+
L.
532+
SECTION-B SECTION.
533+
L.
534+
STOP RUN.
535+
])
536+
537+
AT_CHECK([${COMPILE} -fsyntax-only prog1.cob], [1], ,
538+
[prog1.cob:8: Error: Duplicate paragraph 'L' in the default section
539+
prog1.cob:6: Error: 'L' previously defined here
540+
])
541+
AT_CHECK([${COMPILE} -fsyntax-only prog2.cob], [1], ,
542+
[prog2.cob:8: Error: Duplicate paragraph 'L' in section 'SECTION-A'
543+
prog2.cob:6: Error: 'L' previously defined here
544+
])
545+
AT_CHECK([${COMPILE} -fsyntax-only prog3.cob])
546+
547+
AT_CHECK([${COMPILE} prog1.cob], [1], ,
548+
[prog1.cob:8: Error: Duplicate paragraph 'L' in the default section
549+
prog1.cob:6: Error: 'L' previously defined here
550+
])
551+
AT_CHECK([${COMPILE} prog2.cob], [1], ,
552+
[prog2.cob:8: Error: Duplicate paragraph 'L' in section 'SECTION-A'
553+
prog2.cob:6: Error: 'L' previously defined here
554+
])
555+
AT_CHECK([${COMPILE} prog3.cob])
556+
557+
AT_CHECK([${COMPILE} prog1.cob prog3.cob], [1], ,
558+
[prog1.cob:8: Error: Duplicate paragraph 'L' in the default section
559+
prog1.cob:6: Error: 'L' previously defined here
560+
])
561+
AT_CHECK([${COMPILE} prog2.cob prog3.cob], [1], ,
562+
[prog2.cob:8: Error: Duplicate paragraph 'L' in section 'SECTION-A'
563+
prog2.cob:6: Error: 'L' previously defined here
564+
])
565+
566+
AT_CHECK([${COMPILE} prog3.cob prog1.cob], [1], ,
567+
[prog1.cob:8: Error: Duplicate paragraph 'L' in the default section
568+
prog1.cob:6: Error: 'L' previously defined here
569+
])
570+
AT_CHECK([${COMPILE} prog3.cob prog2.cob], [1], ,
571+
[prog2.cob:8: Error: Duplicate paragraph 'L' in section 'SECTION-A'
572+
prog2.cob:6: Error: 'L' previously defined here
573+
])
574+
575+
AT_CHECK([${COMPILE} prog1.cob prog2.cob], [1], ,
576+
[prog1.cob:8: Error: Duplicate paragraph 'L' in the default section
577+
prog1.cob:6: Error: 'L' previously defined here
578+
])
579+
AT_CHECK([${COMPILE} prog2.cob prog1.cob], [1], ,
580+
[prog2.cob:8: Error: Duplicate paragraph 'L' in section 'SECTION-A'
581+
prog2.cob:6: Error: 'L' previously defined here
582+
])
522583

523584
AT_CLEANUP
524585

0 commit comments

Comments
 (0)