1 /* Type-checking functions */
3 /* Copyright (c) 1994 Stanford University
7 This software is provided under the terms described in
8 the "suif_copyright.h" include file. */
10 #include <suif_copyright.h>
12 #define _MODULE_ "libcheck.a"
15 #include "check_internal.h"
17 /* local function declarations */
18 static void check_fields(tree_node
*tn
, instruction
*i
, type_node
*tbase
);
19 static void check_null_dst(instruction
*i
, tree_node
*tn
);
20 static void check_null_src(instruction
*i
, operand r
, tree_node
*tn
);
25 check_type (tree_node
*tn
, void *)
27 tree_node
*old_node
= current_node
;
30 tree_instr
*ti
= (tree_instr
*)tn
;
31 ti
->instr_map(&check_type_instr
, (void *)tn
, FALSE
);
33 current_node
= old_node
;
38 check_type_instr (instruction
*i
, void *x
)
40 tree_node
*tn
= (tree_node
*)x
;
42 /* check if this is a dummy copy in a tree_for node */
43 boolean is_dummy
= FALSE
;
44 if ((tn
!= NULL
) && (!tn
->list_e()->next())) {
45 assert(tn
->is_instr());
46 tree_instr
*ti
= (tree_instr
*)tn
;
47 tree_node_list
*parent_list
= tn
->parent();
48 tree_node
*grandparent
= parent_list
->parent();
49 if (grandparent
->is_for() && (ti
->instr() == i
)) {
50 tree_for
*tf
= (tree_for
*)grandparent
;
51 if ((parent_list
== tf
->lb_list()) ||
52 (parent_list
== tf
->ub_list()) ||
53 (parent_list
== tf
->step_list())) {
54 if (i
->opcode() == io_cpy
) {
57 problem("tree_for (%u) - missing dummy cpy for operand",
64 if (i
->result_type() == 0) {
65 problem_instr(tn
, i
, "destination has NULL type");
69 if (i
->result_type()->is_modifier()) {
70 problem_instr(tn
, i
, "destination has qualified type");
73 /* check the destination (note: if the destination is an instruction,
74 the type will be checked when the result value is used) */
76 operand dst
= i
->dst_op();
79 problem_instr(tn
, i
, "destination for dummy cpy is not NULL");
81 if (i
->result_type()->unqual()->op() == TYPE_VOID
) {
82 problem_instr(tn
, i
, "dummy cpy has VOID type");
84 } else if (dst
.is_symbol()) {
85 if (!i
->result_type()->compatible(dst
.symbol()->type())) {
86 problem_instr(tn
, i
, "result type doesn't match destination");
90 if (i
->result_type()->op() == TYPE_VOID
) {
93 "void return type with non-null destinaton operand");
97 /* now check the source operands and other conditions associated with
100 // DLH - Check for types in each operand
101 for (unsigned opn
= 0;
102 opn
< i
->num_srcs(); opn
++) {
103 if (i
->src_op(opn
).type() == 0) {
105 "instruction with NULL source_op type");
110 switch (i
->opcode()) {
113 in_rrr
*ri
= (in_rrr
*)i
;
114 check_null_dst(i
, tn
);
115 type_node
*ret_type
= ri
->src_op().type()->unqual();
117 proc_sym
*ps
= tn
->proc();
118 if (!ret_type
->compatible(ps
->type()->return_type())) {
119 problem_instr(tn
, i
, "return value type does not match "
120 "function declaration");
123 if ((ret_type
->op() == TYPE_ARRAY
) ||
124 (ret_type
->op() == TYPE_FUNC
)) {
125 problem_instr(tn
, i
, "invalid return type");
131 in_mbr
*mbri
= (in_mbr
*)i
;
132 check_null_dst(i
, tn
);
133 type_node
*t
= mbri
->src_op().type()->unqual();
134 if ((t
->op() != TYPE_INT
) && (t
->op() != TYPE_ENUM
)) {
135 problem_instr(tn
, i
, "source operand must have type INT or "
144 check_null_dst(i
, tn
);
145 for (unsigned n
= 0; n
< i
->num_srcs(); n
++) {
146 check_null_src(i
, i
->src_op(n
), tn
);
155 in_rrr
*ri
= (in_rrr
*)i
;
156 type_node
*t
= i
->result_type()->unqual();
157 if ((t
->op() != TYPE_INT
) &&
158 (t
->op() != TYPE_ENUM
)) {
159 problem_instr(tn
, i
, "invalid result type");
161 if (!t
->compatible(ri
->src1_op().type()) ||
162 !t
->compatible(ri
->src2_op().type())) {
163 problem_instr(tn
, i
, "source operand does not match "
174 in_rrr
*ri
= (in_rrr
*)i
;
175 boolean bad_type
= FALSE
;
176 type_node
*t
= i
->result_type()->unqual();
177 if ((t
->op() == TYPE_INT
) || (t
->op() == TYPE_ENUM
)) {
178 base_type
*bt
= (base_type
*)t
;
179 if (bt
->is_signed()) {
181 problem_instr(tn
, i
, "result type is not unsigned");
185 problem_instr(tn
, i
, "invalid result type");
189 boolean bad_source
= FALSE
;
190 if (!t
->compatible(ri
->src1_op().type())) {
193 if (i
->opcode() == io_not
) {
194 check_null_src(i
, ri
->src2_op(), tn
);
195 } else if (!t
->compatible(ri
->src2_op().type())) {
199 problem_instr(tn
, i
, "source operand does not match "
214 in_rrr
*ri
= (in_rrr
*)i
;
215 type_node
*t
= i
->result_type()->unqual();
216 type_node
*t1
= ri
->src1_op().type()->unqual();
217 type_node
*t2
= ri
->src2_op().type()->unqual();
219 /* handle pointer addition separately */
220 if ((i
->opcode() == io_add
) && (t
->op() == TYPE_PTR
)) {
224 tptr
= (ptr_type
*)t1
;
226 } else if (t2
->is_ptr()) {
227 tptr
= (ptr_type
*)t2
;
230 problem_instr(tn
, i
, "source operands do not match "
234 if (((toff
->op() != TYPE_INT
) && (toff
->op() != TYPE_ENUM
)) ||
235 (toff
->size() > target
.size
[C_ptr
])) {
236 problem_instr(tn
, i
, "illegal pointer addition");
239 /* check the "fields" annotation (if there is one) */
240 check_fields(tn
, i
, tptr
->ref_type()->unqual());
244 /* check for pointer subtraction */
245 if ((i
->opcode() == io_sub
) && (t1
->op() == TYPE_PTR
)) {
246 if (t2
->op() == TYPE_PTR
) {
247 if (((t
->op() != TYPE_INT
) && (t
->op() != TYPE_ENUM
)) ||
248 (t
->size() != target
.size
[target
.ptr_diff_type
])) {
249 problem_instr(tn
, i
, "invalid result type for "
250 "pointer subtraction");
252 } else if (((t2
->op() == TYPE_INT
) ||
253 (t2
->op() == TYPE_ENUM
)) &&
254 (t2
->size() <= target
.size
[C_ptr
])) {
255 if (t
->op() != TYPE_PTR
) {
256 problem_instr(tn
, i
, "invalid result type for pointer "
260 problem_instr(tn
, i
, "invalid source operands");
265 if ((t
->op() != TYPE_INT
) &&
266 (t
->op() != TYPE_FLOAT
) &&
267 (t
->op() != TYPE_ENUM
)) {
268 problem_instr(tn
, i
, "invalid result type");
270 boolean bad_source
= FALSE
;
271 if (!t
->compatible(t1
)) {
274 if ((i
->opcode() == io_neg
) ||
275 (i
->opcode() == io_abs
)) {
276 check_null_src(i
, ri
->src2_op(), tn
);
277 } else if (!t
->compatible(t2
)) {
281 problem_instr(tn
, i
, "source operand does not match "
289 in_rrr
*ri
= (in_rrr
*)i
;
290 type_node
*t
= i
->result_type()->unqual();
291 if ((t
->op() != TYPE_INT
) &&
292 (t
->op() != TYPE_ENUM
) &&
293 (t
->op() != TYPE_FLOAT
) &&
294 (t
->op() != TYPE_PTR
) &&
295 (t
->op() != TYPE_ARRAY
) &&
296 (t
->op() != TYPE_GROUP
) &&
297 (t
->op() != TYPE_STRUCT
) &&
298 (t
->op() != TYPE_UNION
)) {
299 problem_instr(tn
, i
, "invalid result type");
301 if (t
->size() == 0) {
302 problem_instr(tn
, i
, "invalid result type");
304 type_node
*srct
= ri
->src_op().type()->unqual();
305 if (!t
->compatible(srct
)) {
306 problem_instr(tn
, i
, "source operand does not match result "
309 /* check the "fields" annotation (this should really only be
310 needed for io_cvt instructions but we might as well be safe) */
311 if (srct
->is_ptr()) {
312 check_fields(tn
, i
, ((ptr_type
*)srct
)->ref_type()->unqual());
314 check_null_src(i
, ri
->src2_op(), tn
);
321 in_rrr
*ri
= (in_rrr
*)i
;
323 /* must have "signed" type for asr, "unsigned" for lsr */
324 boolean bad_type
= TRUE
;
325 type_node
*t
= i
->result_type()->unqual();
326 if ((t
->op() == TYPE_INT
) || (t
->op() != TYPE_ENUM
)) {
327 base_type
*bt
= (base_type
*)t
;
328 if (((i
->opcode() != io_asr
) || bt
->is_signed()) &&
329 ((i
->opcode() != io_lsr
) || !bt
->is_signed())) {
334 problem_instr(tn
, i
, "invalid result type");
335 } else if (!t
->compatible(ri
->src_op().type())) {
336 problem_instr(tn
, i
, "source operand does not match result "
340 t
= ri
->shift_cnt_op().type()->unqual();
341 if ((t
->op() == TYPE_INT
) || (t
->op() == TYPE_ENUM
)) {
342 base_type
*bt
= (base_type
*)t
;
343 if (bt
->is_signed()) {
344 problem_instr(tn
, i
, "shift count type is not unsigned ");
347 problem_instr(tn
, i
, "invalid type for shift count");
354 in_rrr
*ri
= (in_rrr
*)i
;
356 type_node
*t
= i
->result_type()->unqual();
357 if ((t
->op() != TYPE_INT
) && (t
->op() != TYPE_ENUM
)) {
358 problem_instr(tn
, i
, "invalid result type");
360 if (!t
->compatible(ri
->src_op().type())) {
361 problem_instr(tn
, i
, "source operand does not match result "
365 t
= ri
->shift_cnt_op().type()->unqual();
366 if ((t
->op() == TYPE_INT
) || (t
->op() == TYPE_ENUM
)) {
367 base_type
*bt
= (base_type
*)t
;
368 if (!bt
->is_signed()) {
369 problem_instr(tn
, i
, "rotation amount type is not signed");
372 problem_instr(tn
, i
, "invalid type for rotation amount");
381 in_rrr
*ri
= (in_rrr
*)i
;
382 type_node
*t
= i
->result_type()->unqual();
383 if (!t
->compatible(type_signed
)) {
384 problem_instr(tn
, i
, "result type of comparison is not "
387 t
= ri
->src1_op().type()->unqual();
388 if ((t
->op() != TYPE_INT
) &&
389 (t
->op() != TYPE_FLOAT
) &&
390 (t
->op() != TYPE_PTR
) &&
391 (t
->op() != TYPE_ENUM
)) {
392 problem_instr(tn
, i
, "invalid source operand type");
393 } else if (!t
->compatible(ri
->src1_op().type())) {
394 problem_instr(tn
, i
, "source operand types do not match");
402 in_bj
*bji
= (in_bj
*)i
;
403 check_null_dst(i
, tn
);
404 if (i
->opcode() == io_jmp
) {
405 check_null_src(i
, bji
->src_op(), tn
);
406 } else if (!type_signed
->compatible(bji
->src_op().type())) {
407 problem_instr(tn
, i
, "branch condition must be ``int''");
413 in_rrr
*ri
= (in_rrr
*)i
;
414 type_node
*t
= i
->result_type()->unqual();
415 if ((t
->op() != TYPE_INT
) &&
416 (t
->op() != TYPE_ENUM
) &&
417 (t
->op() != TYPE_FLOAT
) &&
418 (t
->op() != TYPE_PTR
)) {
419 problem_instr(tn
, i
, "invalid result type");
421 if (ri
->src_op().type() == 0) {
422 problem_instr(tn
, i
, "invalid result type == 0");
425 t
= ri
->src_op().type()->unqual();
426 if ((t
->op() != TYPE_INT
) &&
427 (t
->op() != TYPE_ENUM
) &&
428 (t
->op() != TYPE_FLOAT
) &&
429 (t
->op() != TYPE_PTR
)) {
430 problem_instr(tn
, i
, "invalid source operand type");
432 /* check the "fields" annotation (if there is one) */
434 check_fields(tn
, i
, ((ptr_type
*)t
)->ref_type()->unqual());
436 check_null_src(i
, ri
->src2_op(), tn
);
441 in_ldc
*ldci
= (in_ldc
*)i
;
442 type_node
*t
= i
->result_type()->unqual();
443 immed v
= ldci
->value();
444 boolean bad_type
= FALSE
;
447 case im_extended_int
: {
448 /* allow integers to be treated as pointers (e.g. NULL) */
449 if ((t
->op() != TYPE_INT
) &&
450 (t
->op() != TYPE_ENUM
) &&
451 (t
->op() != TYPE_PTR
)) {
457 case im_extended_float
: {
458 if (t
->op() != TYPE_FLOAT
) {
464 if (t
->op() != TYPE_PTR
) {
470 problem_instr(tn
, i
, "illegal constant value");
474 problem_instr(tn
, i
, "value does not match result type");
480 in_rrr
*ri
= (in_rrr
*)i
;
481 type_node
*t
= i
->result_type()->unqual();
482 type_node
*st
= ri
->src_addr_op().type()->unqual();
483 if (st
->op() != TYPE_PTR
) {
484 problem_instr(tn
, i
, "source address is not a pointer");
486 ptr_type
*pt
= (ptr_type
*)st
;
487 if (!t
->compatible(pt
->ref_type())) {
488 problem_instr(tn
, i
, "incorrect return type");
489 } else if ((t
->op() == TYPE_VOID
) ||
490 (t
->op() == TYPE_FUNC
) ||
492 problem_instr(tn
, i
, "illegal type");
495 check_null_src(i
, ri
->src2_op(), tn
);
500 in_rrr
*ri
= (in_rrr
*)i
;
501 check_null_dst(i
, tn
);
502 type_node
*dt
= ri
->dst_addr_op().type()->unqual();
503 if (dt
->op() != TYPE_PTR
) {
504 problem_instr(tn
, i
, "destination address is not a pointer");
506 ptr_type
*pt
= (ptr_type
*)dt
;
507 type_node
*t
= pt
->ref_type()->unqual();
508 if (!t
->compatible(ri
->src_op().type())) {
509 problem_instr(tn
, i
, "incorrect source type");
510 } else if ((t
->op() == TYPE_VOID
) ||
511 (t
->op() == TYPE_FUNC
) ||
512 (t
->op() == TYPE_ARRAY
)) {
513 problem_instr(tn
, i
, "illegal type");
520 in_rrr
*ri
= (in_rrr
*)i
;
521 check_null_dst(i
, tn
);
522 type_node
*st
= ri
->src_addr_op().type()->unqual();
523 type_node
*dt
= ri
->dst_addr_op().type()->unqual();
524 boolean bad_ptr
= FALSE
;
525 if (dt
->op() != TYPE_PTR
) {
526 problem_instr(tn
, i
, "destination address is not a pointer");
529 if (st
->op() != TYPE_PTR
) {
530 problem_instr(tn
, i
, "source address is not a pointer");
534 ptr_type
*spt
= (ptr_type
*)st
;
535 ptr_type
*dpt
= (ptr_type
*)dt
;
536 type_node
*t
= spt
->ref_type()->unqual();
538 if (!t
->compatible(dpt
->ref_type())) {
539 problem_instr(tn
, i
, "pointer types do not match");
540 } else if ((t
->op() == TYPE_VOID
) ||
541 (t
->op() == TYPE_FUNC
) ||
542 (t
->op() == TYPE_ARRAY
)) {
543 problem_instr(tn
, i
, "illegal type");
550 in_cal
*cali
= (in_cal
*)i
;
551 type_node
*t
= cali
->addr_op().type()->unqual();
552 func_type
*ft
= NULL
;
553 if (t
->op() == TYPE_PTR
) {
554 ptr_type
*pt
= (ptr_type
*)t
;
555 type_node
*rt
= pt
->ref_type()->unqual();
556 if (rt
->op() == TYPE_FUNC
) {
557 ft
= (func_type
*)rt
;
561 problem_instr(tn
, i
, "bad target address");
563 if (!ft
->return_type()->compatible(i
->result_type())) {
564 problem_instr(tn
, i
, "result type does not match "
565 "function declaration");
567 if (ft
->return_type()->unqual()->is_array() ||
568 ft
->return_type()->unqual()->is_func()) {
569 problem_instr(tn
, i
, "illegal return type for call");
571 if (ft
->args_known()) {
572 unsigned numargs
= ft
->num_args();
573 if (cali
->num_args() < numargs
) {
574 problem_instr(tn
, i
, "too few arguments");
575 numargs
= cali
->num_args();
576 } else if ((cali
->num_args() > numargs
) &&
577 !ft
->has_varargs()) {
578 problem_instr(tn
, i
, "too many arguments");
580 for (unsigned n
= 0; n
< numargs
; n
++) {
581 if (!ft
->arg_type(n
)->compatible
582 (cali
->argument(n
).type())) {
583 problem_instr(tn
, i
, "argument does not match "
584 "function declaration");
593 in_array
*arri
= (in_array
*)i
;
595 /* the result type may be a pointer of any sort */
596 if (arri
->result_type()->unqual()->op() != TYPE_PTR
) {
597 problem_instr(tn
, i
, "result type is not a pointer");
600 /* check the type of the offset operand */
601 type_node
*toff
= arri
->offset_op().type()->unqual();
602 if ((toff
->op() != TYPE_VOID
) &&
603 (toff
->op() != TYPE_INT
) &&
604 (toff
->op() != TYPE_ENUM
)) {
605 problem_instr(tn
, i
, "invalid type for offset operand");
608 /* check the base operand type */
609 type_node
*tbase
= arri
->base_op().type()->unqual();
610 if (tbase
->op() == TYPE_PTR
) {
611 ptr_type
*pt
= (ptr_type
*)tbase
;
612 tbase
= pt
->ref_type()->unqual();
614 problem_instr(tn
, i
, "invalid type for base operand");
618 /* check each dimension */
619 for (unsigned d
= 0; d
< arri
->dims(); d
++) {
620 array_type
*at
= (array_type
*)tbase
;
621 if (at
&& (at
->op() != TYPE_ARRAY
)) {
622 problem_instr(tn
, i
, "array type does not match");
625 /* check the index type */
626 type_node
*tind
= arri
->index(d
).type()->unqual();
627 if ((tind
->op() != TYPE_INT
) &&
628 (tind
->op() != TYPE_ENUM
)) {
629 problem_instr(tn
, i
, "incorrect type for index %u", d
);
632 operand b
= arri
->bound(d
);
635 problem_instr(tn
, i
, "missing bound %u", d
);
638 /* check the bound type */
639 type_node
*tbnd
= b
.type()->unqual();
640 if ((tbnd
->op() != TYPE_INT
) &&
641 (tbnd
->op() != TYPE_ENUM
)) {
642 problem_instr(tn
, i
, "incorrect type for bound %u", d
);
645 /* compare values of bounds */
646 if (at
->lower_bound().is_constant() &&
647 at
->upper_bound().is_constant()) {
649 int bndval
= 1 + at
->upper_bound().constant() -
650 at
->lower_bound().constant();
653 (b
.instr()->opcode() == io_ldc
)) {
654 in_ldc
*ldci
= (in_ldc
*)b
.instr();
655 if (ldci
->value().is_integer() &&
656 (ldci
->value().integer() != bndval
)) {
657 problem_instr(tn
, i
, "bound %u does not "
665 /* get the next element type */
667 tbase
= at
->elem_type()->unqual();
673 /* give up now if we don't know the element type */
676 /* check that the element size is correct */
677 if (arri
->elem_size() != (unsigned)tbase
->size()) {
678 problem_instr(tn
, i
, "element size does not match array type");
681 /* check the "fields" annotation (if there is one) */
682 check_fields(tn
, i
, tbase
);
688 problem_instr(tn
, i
, "unexpected opcode: %s",
689 if_ops_name(i
->opcode()));
696 check_fields (tree_node
*tn
, instruction
*i
, type_node
*tbase
)
698 /* try to figure out the field (if any) */
700 if (i
->are_annotations()) {
701 flds
= i
->annotes()->peek_annote(k_fields
);
704 immed_list_iter
ili(flds
->immeds());
705 while (!ili
.is_empty()) {
706 const char *fld
= ili
.step().string();
707 if (!tbase
->is_struct()) {
708 problem_instr(tn
, i
, "fields annotation doesn't match type");
711 struct_type
*stbase
= (struct_type
*)tbase
;
712 unsigned fldnum
= stbase
->find_field_by_name(fld
);
713 if (fldnum
>= stbase
->num_fields()) {
714 problem_instr(tn
, i
, "cannot find field '%s'", fld
);
717 tbase
= stbase
->field_type(fldnum
)->unqual();
724 check_null_dst (instruction
*i
, tree_node
*tn
)
726 if (!i
->dst_op().is_null()) {
727 problem_instr(tn
, i
, "unexpected destination operand");
729 if (!i
->result_type()->op() == TYPE_VOID
) {
730 problem_instr(tn
, i
, "result type should be void");
736 check_null_src (instruction
*i
, operand r
, tree_node
*tn
)
739 problem_instr(tn
, i
, "unused source operand is not null");
741 if (!i
->result_type()->op() == TYPE_VOID
) {
742 problem_instr(tn
, i
, "non-void result type");