Skip to content

Commit dd640a2

Browse files
Fix runtime checkins for subscripts (#277)
1 parent 9ffdca8 commit dd640a2

File tree

6 files changed

+43
-46
lines changed

6 files changed

+43
-46
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
2121
* Fix `INSPECT` statement (#268)
2222
* Fix error handlings of 0 divisions (#273)
2323
* Fix an error of comparing large numbers (#275)
24+
* Fix checkings for subscripts (#277)
2425
### Optimized
2526
* Optimize the file reading process (#257)
2627

cobj/codegen.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,7 @@ static void joutput_integer(cb_tree x) {
12101210
case CB_TAG_BINARY_OP:
12111211
p = CB_BINARY_OP(x);
12121212
if (p->op == '^') {
1213-
joutput("(int) pow (");
1213+
joutput("(int) Math.pow (");
12141214
joutput_integer(p->x);
12151215
joutput(", ");
12161216
joutput_integer(p->y);

cobj/typeck.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -767,29 +767,32 @@ cb_tree cb_build_identifier(cb_tree x) {
767767
cb_int(p->occurs_min), cb_int(p->occurs_max),
768768
cb_build_string0(
769769
(ucharptr)(cb_field(p->occurs_depending)->name)));
770-
e2 = cb_build_funcall_4(
770+
e2 = cb_build_funcall_5(
771771
"CobolCheck.checkSubscript", cb_build_cast_integer(sub),
772772
cb_int1, cb_build_cast_integer(p->occurs_depending),
773-
cb_build_string0((ucharptr)name));
773+
cb_build_string0((ucharptr)name),
774+
cb_int(strlen((ucharptr)name)));
774775
} else {
775776
e1 = cb_build_funcall_4(
776777
"CobolCheck.checkOdo", cb_int(p->occurs_max),
777778
cb_int(p->occurs_min), cb_int(p->occurs_max),
778779
cb_build_string0(
779780
(ucharptr)(cb_field(p->occurs_depending)->name)));
780-
e2 = cb_build_funcall_4("CobolCheck.checkSubscript",
781+
e2 = cb_build_funcall_5("CobolCheck.checkSubscript",
781782
cb_build_cast_integer(sub), cb_int1,
782783
cb_int(p->occurs_max),
783-
cb_build_string0((ucharptr)name));
784+
cb_build_string0((ucharptr)name),
785+
cb_int(strlen((ucharptr)name)));
784786
}
785787
r->check = cb_list_add(r->check, e1);
786788
r->check = cb_list_add(r->check, e2);
787789
} else {
788790
if (!CB_LITERAL_P(sub)) {
789-
e1 = cb_build_funcall_4("CobolCheck.checkSubscript",
791+
e1 = cb_build_funcall_5("CobolCheck.checkSubscript",
790792
cb_build_cast_integer(sub), cb_int1,
791793
cb_int(p->occurs_max),
792-
cb_build_string0((ucharptr)name));
794+
cb_build_string0((ucharptr)name),
795+
cb_int(strlen((ucharptr)name)));
793796
r->check = cb_list_add(r->check, e1);
794797
}
795798
}

libcobj/app/src/main/java/jp/osscons/opensourcecobol/libcobj/common/CobolCheck.java

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,25 @@
2323
import jp.osscons.opensourcecobol.libcobj.exceptions.CobolRuntimeException;
2424
import jp.osscons.opensourcecobol.libcobj.exceptions.CobolStopRunException;
2525

26-
/** TODO 暫定的に作ったクラス ここに実装されたメソッドは別の適切なクラスに実装する、または適切なクラス名に変更する */
2726
public class CobolCheck {
28-
public static void checkSubscript(int i, int min, int max, byte[] name) {
29-
// TODO 実装 (libcob/common.c)
30-
}
31-
32-
public static void checkSubscript(long i, int min, int max, byte[] name) {
33-
CobolCheck.checkSubscript((int) i, min, max, name);
27+
public static void checkSubscript(int i, int min, int max, byte[] name, int len)
28+
throws CobolStopRunException {
29+
if (i < min || max < i) {
30+
CobolRuntimeException.setException(CobolExceptionId.COB_EC_BOUND_SUBSCRIPT);
31+
CobolUtil.runtimeError(
32+
String.format("Subscript of '%s' out of bounds: %d", new String(name), i));
33+
CobolStopRunException.stopRunAndThrow(1);
34+
}
3435
}
3536

36-
public static void checkSubscript(long i, int min, int max, CobolDataStorage name) {
37-
// TODO 実装
37+
public static void checkSubscript(long i, int min, int max, byte[] name, int len)
38+
throws CobolStopRunException {
39+
CobolCheck.checkSubscript((int) i, min, max, name, len);
3840
}
3941

40-
public static void checkSubscript(CobolDataStorage i, int min, int max, byte[] name) {
41-
// TODO 実装 (libcob/common.c)
42+
public static void checkSubscript(long i, int min, int max, CobolDataStorage name, int len)
43+
throws CobolStopRunException {
44+
CobolCheck.checkSubscript((int) i, min, max, name.getByteArrayRef(0, len), len);
4245
}
4346

4447
/**
@@ -53,9 +56,12 @@ public static void checkSubscript(CobolDataStorage i, int min, int max, byte[] n
5356
public static void checkOdo(int i, int min, int max, String name) throws CobolStopRunException {
5457
if (i < min || max < i) {
5558
CobolRuntimeException.setException(CobolExceptionId.COB_EC_BOUND_SUBSCRIPT);
56-
// TODO ここを正しく実装する
57-
System.err.println("check odo error");
59+
CobolUtil.runtimeError(String.format("OCCURS DEPENDING ON '%s' out of bounds: %d", name, i));
5860
CobolStopRunException.stopRunAndThrow(1);
5961
}
6062
}
63+
64+
public static void checkOdo(int i, int min, int max, byte[] name) throws CobolStopRunException {
65+
CobolCheck.checkOdo(i, min, max, new String(name));
66+
}
6167
}

tests/atlocal.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ FLAGS_JP_COMPAT_NONE="${FLAGS_NONE} ${CONF_JP_COMPAT}"
4242
FLAGS_LIMIT_TEST="${FLAGS} ${CONF_LIMIT_TEST}"
4343
COMPILE="${COBJ} ${FLAGS}"
4444
COMPILE_DEFAULT="${COBJ} ${FLAGS_NONE}"
45+
COMPILE_SUBSCRIPT="${COBJ} ${FLAGS_JP_COMPAT}"
4546
COMPILE_JP_COMPAT="${COBJ} ${FLAGS_JP_COMPAT}"
4647
COMPILE_JP_COMPAT_DEFAULT="${COBJ} ${FLAGS_JP_COMPAT_NONE}"
4748
COMPILE_LIMIT_TEST="${COBJ} ${FLAGS_LIMIT_TEST}"

tests/run.src/subscripts.at

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
# 1) TODO
2727

2828
AT_SETUP([non-numeric subscript])
29-
AT_CHECK([${SKIP_TEST}])
3029

3130
AT_DATA([prog.cob], [
3231
IDENTIFICATION DIVISION.
@@ -55,7 +54,6 @@ AT_CLEANUP
5554
# 2) DONE
5655

5756
AT_SETUP([The range of subscripts])
58-
AT_CHECK([${SKIP_TEST}])
5957

6058
AT_DATA([prog.cob], [
6159
IDENTIFICATION DIVISION.
@@ -96,7 +94,6 @@ AT_CLEANUP
9694

9795

9896
AT_SETUP([Subscript out of bounds (1)])
99-
AT_CHECK([${SKIP_TEST}])
10097

10198
AT_DATA([prog.cob], [
10299
IDENTIFICATION DIVISION.
@@ -112,7 +109,7 @@ AT_DATA([prog.cob], [
112109
STOP RUN.
113110
])
114111

115-
AT_CHECK([${COMPILE} prog.cob])
112+
AT_CHECK([${COMPILE_SUBSCRIPT} prog.cob])
116113
AT_CHECK([java prog], [1], ,
117114
[prog.cob:10: libcobj: Subscript of 'X' out of bounds: 0
118115
])
@@ -121,7 +118,6 @@ AT_CLEANUP
121118

122119

123120
AT_SETUP([Subscript out of bounds (2)])
124-
AT_CHECK([${SKIP_TEST}])
125121

126122
AT_DATA([prog.cob], [
127123
IDENTIFICATION DIVISION.
@@ -137,15 +133,14 @@ AT_DATA([prog.cob], [
137133
STOP RUN.
138134
])
139135

140-
AT_CHECK([${COMPILE} prog.cob])
136+
AT_CHECK([${COMPILE_SUBSCRIPT} prog.cob])
141137
AT_CHECK([java prog], [1], ,
142138
[prog.cob:10: libcobj: Subscript of 'X' out of bounds: 11
143139
])
144140

145141
AT_CLEANUP
146142

147143
AT_SETUP([Subscript out of bounds (3-1)])
148-
AT_CHECK([${SKIP_TEST}])
149144

150145
AT_DATA([prog.cob], [
151146
IDENTIFICATION DIVISION.
@@ -161,15 +156,14 @@ AT_DATA([prog.cob], [
161156
STOP RUN.
162157
])
163158

164-
AT_CHECK([${COMPILE} prog.cob])
159+
AT_CHECK([${COMPILE_SUBSCRIPT} prog.cob])
165160
AT_CHECK([java prog], [1], ,
166161
[prog.cob:10: libcobj: Subscript of 'X' out of bounds: 11
167162
])
168163

169164
AT_CLEANUP
170165

171166
AT_SETUP([Subscript out of bounds (3-2)])
172-
AT_CHECK([${SKIP_TEST}])
173167

174168
AT_DATA([prog.cob], [
175169
IDENTIFICATION DIVISION.
@@ -185,15 +179,14 @@ AT_DATA([prog.cob], [
185179
STOP RUN.
186180
])
187181

188-
AT_CHECK([${COMPILE} prog.cob])
182+
AT_CHECK([${COMPILE_SUBSCRIPT} prog.cob])
189183
AT_CHECK([java prog], [1], ,
190184
[prog.cob:10: libcobj: Subscript of 'X' out of bounds: 11
191185
])
192186

193187
AT_CLEANUP
194188

195189
AT_SETUP([Subscript out of bounds (3-3)])
196-
AT_CHECK([${SKIP_TEST}])
197190

198191
AT_DATA([prog.cob], [
199192
IDENTIFICATION DIVISION.
@@ -209,15 +202,14 @@ AT_DATA([prog.cob], [
209202
STOP RUN.
210203
])
211204

212-
AT_CHECK([${COMPILE} prog.cob])
205+
AT_CHECK([${COMPILE_SUBSCRIPT} prog.cob])
213206
AT_CHECK([java prog], [1], ,
214207
[prog.cob:10: libcobj: Subscript of 'X' out of bounds: 11
215208
])
216209

217210
AT_CLEANUP
218211

219212
AT_SETUP([Subscript out of bounds (3-4)])
220-
AT_CHECK([${SKIP_TEST}])
221213

222214
AT_DATA([prog.cob], [
223215
IDENTIFICATION DIVISION.
@@ -233,15 +225,14 @@ AT_DATA([prog.cob], [
233225
STOP RUN.
234226
])
235227

236-
AT_CHECK([${COMPILE} prog.cob])
228+
AT_CHECK([${COMPILE_SUBSCRIPT} prog.cob])
237229
AT_CHECK([java prog], [1], ,
238230
[prog.cob:10: libcobj: Subscript of 'X' out of bounds: 11
239231
])
240232

241233
AT_CLEANUP
242234

243235
AT_SETUP([Value of DEPENDING ON N out of bounds (lower)])
244-
AT_CHECK([${SKIP_TEST}])
245236

246237
AT_DATA([prog.cob], [
247238
IDENTIFICATION DIVISION.
@@ -257,7 +248,7 @@ AT_DATA([prog.cob], [
257248
STOP RUN.
258249
])
259250

260-
AT_CHECK([${COMPILE} prog.cob])
251+
AT_CHECK([${COMPILE_SUBSCRIPT} prog.cob])
261252
AT_CHECK([java prog], [1], ,
262253
[prog.cob:10: libcobj: OCCURS DEPENDING ON 'N' out of bounds: 3
263254
])
@@ -266,7 +257,6 @@ AT_CLEANUP
266257

267258

268259
AT_SETUP([Value of DEPENDING ON N out of bounds (upper)])
269-
AT_CHECK([${SKIP_TEST}])
270260

271261
AT_DATA([prog.cob], [
272262
IDENTIFICATION DIVISION.
@@ -282,7 +272,7 @@ AT_DATA([prog.cob], [
282272
STOP RUN.
283273
])
284274

285-
AT_CHECK([${COMPILE} prog.cob])
275+
AT_CHECK([${COMPILE_SUBSCRIPT} prog.cob])
286276
AT_CHECK([java prog], [1], ,
287277
[prog.cob:10: libcobj: OCCURS DEPENDING ON 'N' out of bounds: 7
288278
])
@@ -337,7 +327,6 @@ AT_CLEANUP
337327

338328

339329
AT_SETUP([Subscript bounds with ODO])
340-
AT_CHECK([${SKIP_TEST}])
341330

342331
AT_DATA([prog.cob], [
343332
IDENTIFICATION DIVISION.
@@ -353,7 +342,7 @@ AT_DATA([prog.cob], [
353342
STOP RUN.
354343
])
355344

356-
AT_CHECK([${COMPILE} prog.cob])
345+
AT_CHECK([${COMPILE_SUBSCRIPT} prog.cob])
357346
AT_CHECK([java prog], [1], ,
358347
[prog.cob:10: libcobj: Subscript of 'X' out of bounds: 5
359348
])
@@ -364,7 +353,6 @@ AT_CLEANUP
364353
##
365354

366355
AT_SETUP([Subscript by arithmetic expression])
367-
AT_CHECK([${SKIP_TEST}])
368356

369357
AT_DATA([prog.cob], [
370358
IDENTIFICATION DIVISION.
@@ -381,14 +369,13 @@ AT_DATA([prog.cob], [
381369
STOP RUN.
382370
])
383371

384-
AT_CHECK([${COMPILE} prog.cob])
372+
AT_CHECK([${COMPILE_SUBSCRIPT} prog.cob])
385373
AT_CHECK([java prog], [0], [24])
386374

387375
AT_CLEANUP
388376

389377

390378
AT_SETUP([Subscript out of bounds in MOVE (1)])
391-
AT_CHECK([${SKIP_TEST}])
392379

393380
AT_DATA([prog.cob], [
394381
IDENTIFICATION DIVISION.
@@ -404,7 +391,7 @@ AT_DATA([prog.cob], [
404391
STOP RUN.
405392
])
406393

407-
AT_CHECK([${COMPILE} prog.cob])
394+
AT_CHECK([${COMPILE_SUBSCRIPT} prog.cob])
408395
AT_CHECK([java prog], [1], ,
409396
[prog.cob:11: libcobj: Subscript of 'X' out of bounds: 0
410397
])
@@ -413,7 +400,6 @@ AT_CLEANUP
413400

414401

415402
AT_SETUP([Subscript out of bounds in MOVE (2)])
416-
AT_CHECK([${SKIP_TEST}])
417403

418404
AT_DATA([prog.cob], [
419405
IDENTIFICATION DIVISION.
@@ -429,7 +415,7 @@ AT_DATA([prog.cob], [
429415
STOP RUN.
430416
])
431417

432-
AT_CHECK([${COMPILE} prog.cob])
418+
AT_CHECK([${COMPILE_SUBSCRIPT} prog.cob])
433419
AT_CHECK([java prog], [1], ,
434420
[prog.cob:11: libcobj: Subscript of 'X' out of bounds: 0
435421
])

0 commit comments

Comments
 (0)