Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cobc/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -3267,6 +3267,12 @@ output_stmt (cb_tree x)
output_line ("cob_exception_code = 0;");
}

if (cb_zero_division_error && p->name &&
((strcmp (p->name, "DIVIDE") == 0) || (strcmp (p->name, "COMPUTE") == 0)) &&
(!p->handler1 && !p->handler2)) {
output_line ("cob_error_on_exit_flag = 1;");
}

if (p->null_check) {
output_stmt (p->null_check);
}
Expand Down
1 change: 1 addition & 0 deletions cobc/config.def
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ CB_CONFIG_BOOLEAN (cb_switch_no_mnemonic, "switch-no-mnemonic")
CB_CONFIG_BOOLEAN (cb_allow_is_in_sort_key_spec, "allow-is-in-sort-key-spec")
CB_CONFIG_BOOLEAN (cb_allow_search_key_in_rhs, "allow-search-key-in-rhs")
CB_CONFIG_BOOLEAN (cb_ignore_invalid_record_contains, "ignore-invalid-record-contains")
CB_CONFIG_BOOLEAN (cb_zero_division_error, "zero_division_error")
CB_CONFIG_SUPPORT (cb_author_paragraph, "author-paragraph")
CB_CONFIG_SUPPORT (cb_memory_size_clause, "memory-size-clause")
CB_CONFIG_SUPPORT (cb_multiple_file_tape_clause, "multiple-file-tape-clause")
Expand Down
6 changes: 6 additions & 0 deletions cobc/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2251,6 +2251,12 @@ cb_build_binary_op (cb_tree x, int op, cb_tree y)
if (x == cb_error_node || y == cb_error_node) {
return cb_error_node;
}
if (cb_zero_division_error && op == '/') {
y = cb_check_zero_division (y);
if (y == cb_error_node) {
return cb_error_node;
}
}
category = CB_CATEGORY_NUMERIC;
break;

Expand Down
1 change: 1 addition & 0 deletions cobc/tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ extern int cb_fits_long_long (cb_tree x);
extern int cb_get_int (cb_tree x);
extern int cb_is_digist_data (cb_tree x);
extern long long cb_get_long_long (cb_tree x);
extern cb_tree cb_check_zero_division(cb_tree x);

/*
* Constants
Expand Down
19 changes: 19 additions & 0 deletions cobc/typeck.c
Original file line number Diff line number Diff line change
Expand Up @@ -7717,3 +7717,22 @@ cb_build_write_advancing_page (cb_tree pos)

return cb_int (opt | COB_WRITE_PAGE);
}

cb_tree
cb_check_zero_division (cb_tree x)
{
if (x == cb_error_node) {
return cb_error_node;
}

if (! CB_NUMERIC_LITERAL_P (x)) {
return x;
}

if (cb_get_int(x) == 0) {
cb_error_x (x, _("Detected division by zero."));
return cb_error_node;
}

return x;
}
1 change: 1 addition & 0 deletions config/default-en.conf
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,4 @@ switch-no-mnemonic: no
allow-is-in-sort-key-spec: no
allow-search-key-in-rhs: no
ignore-invalid-record-contains: no
zero_division_error: no
1 change: 1 addition & 0 deletions config/default-jp.conf
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,4 @@ switch-no-mnemonic: no
allow-is-in-sort-key-spec: no
allow-search-key-in-rhs: no
ignore-invalid-record-contains: no
zero_division_error: yes
1 change: 1 addition & 0 deletions config/default.conf
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,4 @@ switch-no-mnemonic: no
allow-is-in-sort-key-spec: no
allow-search-key-in-rhs: no
ignore-invalid-record-contains: no
zero_division_error: no
1 change: 1 addition & 0 deletions config/jp-compat.conf
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ switch-no-mnemonic: yes
allow-is-in-sort-key-spec: yes
allow-search-key-in-rhs: yes
ignore-invalid-record-contains: yes
zero_division_error: yes

# Value: 'any', 'fatal', 'never'
abort-on-io-exception: fatal
Expand Down
1 change: 1 addition & 0 deletions libcob/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ struct cob_module *cob_current_module = NULL;

int cob_initialized = 0;
int cob_exception_code = 0;
int cob_error_on_exit_flag = 0;

int cob_call_params = 0;
int cob_save_call_params = 0;
Expand Down
1 change: 1 addition & 0 deletions libcob/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ enum cob_exception_id {

COB_EXPIMP int cob_initialized;
COB_EXPIMP int cob_exception_code;
COB_EXPIMP int cob_error_on_exit_flag;

COB_EXPIMP struct cob_module *cob_current_module;

Expand Down
4 changes: 4 additions & 0 deletions libcob/numeric.c
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,10 @@ cob_decimal_div (cob_decimal *d1, cob_decimal *d2)
if (unlikely(mpz_sgn (d2->value) == 0)) {
d1->scale = DECIMAL_NAN;
cob_set_exception (COB_EC_SIZE_ZERO_DIVIDE);
if (cob_error_on_exit_flag) {
cob_runtime_error ("Detected division by zero.");
cob_stop_run (1);
}
return;
}
if (unlikely(mpz_sgn (d1->value) == 0)) {
Expand Down
4 changes: 4 additions & 0 deletions po/ja.po
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,10 @@ msgstr "LOCK
msgid "Invalid mnemonic name"
msgstr "�����ʺ����Ը�Ǥ�"

#: cobc/typeck.c:7733
msgid "Detected division by zero."
msgstr "�����Ǥν��������Ф���ޤ�����"

#: cobc/pplex.l:157
msgid "PROCESS statement is ignored"
msgstr "PROCESS ʸ��̵�뤵��ޤ�"
Expand Down
3 changes: 2 additions & 1 deletion tests/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,8 @@ jp_compat_DEPENDENCIES = \
jp-compat.src/greater-less-than-equal.at \
jp-compat.src/file-desc.at \
jp-compat.src/abort-on-file-error.at \
jp-compat.src/system-routine.at
jp-compat.src/system-routine.at \
jp-compat.src/catch-exception.at

EXTRA_DIST = $(srcdir)/package.m4 $(TESTS) \
$(syntax_DEPENDENCIES) \
Expand Down
1 change: 1 addition & 0 deletions tests/jp-compat.at
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ m4_include([greater-less-than-equal.at])
m4_include([file-desc.at])
m4_include([abort-on-file-error.at])
m4_include([system-routine.at])
m4_include([catch-exception.at])
228 changes: 228 additions & 0 deletions tests/jp-compat.src/catch-exception.at
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
# 1) DONE

AT_SETUP([Divide by zero: by '0' - option yes])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC 9.
PROCEDURE DIVISION.
MOVE 1 TO X.
DIVIDE X BY 0 GIVING X.
GOBACK.
])

AT_CHECK([${COMPILE_JP_COMPAT} prog.cob], [1], ,
[prog.cob:9: Error: Detected division by zero.
])

AT_CLEANUP


# 2) DONE

AT_SETUP([Divide by zero: by '0' - option no])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC 9.
PROCEDURE DIVISION.
MOVE 1 TO X.
DIVIDE X BY 0 GIVING X.
DISPLAY X.
GOBACK.
])

AT_CHECK([${COMPILE} prog.cob])
AT_CHECK([./prog], [0],
[1
])

AT_CLEANUP


# 3) DONE

AT_SETUP([Divide by zero: by variable - option yes])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC 9.
01 Y PIC 9.
PROCEDURE DIVISION.
MOVE 1 TO X.
MOVE 0 TO Y.
DIVIDE X BY Y GIVING X.
GOBACK.
])

AT_CHECK([${COMPILE_JP_COMPAT} prog.cob])
AT_CHECK([./prog], [1], ,
[prog.cob:11: libcob: Detected division by zero.
])

AT_CLEANUP


# 4) DONE

AT_SETUP([Divide by zero: by variable - option no])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC 9.
01 Y PIC 9.
PROCEDURE DIVISION.
MOVE 1 TO X.
MOVE 0 TO Y.
DIVIDE X BY Y GIVING X.
DISPLAY X.
GOBACK.
])

AT_CHECK([${COMPILE} prog.cob])
AT_CHECK([./prog], [0],
[1
])

AT_CLEANUP

# 5) DONE

AT_SETUP([Divide by zero: by '0' compute - option yes])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC 9.
PROCEDURE DIVISION.
MOVE 1 TO X.
COMPUTE X = X / 0.
GOBACK.
])

AT_CHECK([${COMPILE_JP_COMPAT} prog.cob], [1], ,
[prog.cob:9: Error: Detected division by zero.
])

AT_CLEANUP


# 6) DONE

AT_SETUP([Divide by zero: by '0' compute - option no])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC 9.
PROCEDURE DIVISION.
MOVE 1 TO X.
COMPUTE X = X / 0.
DISPLAY X.
GOBACK.
])

AT_CHECK([${COMPILE} prog.cob])
AT_CHECK([./prog], [0],
[1
])

AT_CLEANUP


# 7) DONE

AT_SETUP([Divide by zero: by variable compute - option yes])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC 9.
01 Y PIC 9.
PROCEDURE DIVISION.
MOVE 1 TO X.
MOVE 0 TO Y.
COMPUTE X = X / Y.
GOBACK.
])

AT_CHECK([${COMPILE_JP_COMPAT} prog.cob])
AT_CHECK([./prog], [1], ,
[prog.cob:11: libcob: Detected division by zero.
])

AT_CLEANUP


# 8) DONE

AT_SETUP([Divide by zero: by variable compute - option no])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC 9.
01 Y PIC 9.
PROCEDURE DIVISION.
MOVE 1 TO X.
MOVE 0 TO Y.
COMPUTE X = X / Y.
DISPLAY X.
GOBACK.
])

AT_CHECK([${COMPILE} prog.cob])
AT_CHECK([./prog], [0],
[1
])

AT_CLEANUP


# 9) DONE

AT_SETUP([Divide by zero: by variable with on size error])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC 9.
01 Y PIC 9.
PROCEDURE DIVISION.
MOVE 1 TO X.
MOVE 0 TO Y.
COMPUTE X = X / Y
ON SIZE ERROR
DISPLAY "ON SIZE ERROR"
END-COMPUTE.
GOBACK.
])

AT_CHECK([${COMPILE_JP_COMPAT} prog.cob])
AT_CHECK([./prog], [0],
[ON SIZE ERROR
])

AT_CLEANUP