2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 /* $Id: l_misc.c,v 3.8 1994/06/24 12:04:47 ceriel Exp $ */
6 /* Lint miscellaneous routines */
12 #include <alloc.h> /* for st_free */
13 #include "interface.h"
15 #include <flt_arith.h>
17 #include "arith.h" /* definition arith */
18 #include "label.h" /* definition label */
22 #include "code.h" /* RVAL etc */
30 extern char *symbol2str();
31 extern struct type *func_type;
33 PRIVATE lint_enum_arith();
34 PRIVATE lint_conversion();
35 PRIVATE int numsize();
37 check_hiding(idf, lvl, sc)
42 /* Checks if there is already a definition for this non-extern
43 name on a more global level.
45 struct def *def = idf->id_def;
47 if ( def && def->df_level < lvl
48 && ! ( lvl == L_FORMAL2
49 || def->df_level == L_UNIVERSAL
54 warning("%s is already defined as a %s",
56 def->df_level == L_GLOBAL ? "global" :
57 def->df_level == L_FORMAL2 ? "formal" :
66 /* Does additional checking on a newly constructed expr node
69 Some code in this routine could be contracted, but since
70 I am not sure we have covered the entire ground, we'll
71 leave the contracting for some rainy day.
73 register struct expr *left = expr->OP_LEFT;
74 register struct expr *right = expr->OP_RIGHT;
75 register int oper = expr->OP_OPER;
77 left == 0 ? 0 : /* for monadics */
78 left->ex_type->tp_fund;
80 right == 0 ? 0 : /* for ( without parameters */
81 right->ex_type->tp_fund;
83 /* In ch7.c, in ch7asgn(), a combined operator/assignment
84 is hammered into correctness by repeated application of
85 ch7bin(), which calls new_oper(), which calls lint_new_oper().
86 These spurious calls understandably cause spurious error
87 messages, which we don't like. So we try to suppress these
88 wierd calls here. This refers to the code marked
89 this is really $#@&*%$# !
103 /* is the left operand wierd? */
104 if ( left->ex_class == Value
105 && left->VL_CLASS == Const
106 && left->VL_VALUE == 0
114 lint_conversion(right, l_fund);
118 lint_conversion(right, l_fund);
120 lint_enum_arith(l_fund, oper, r_fund);
124 lint_conversion(right, l_fund);
129 warning("negating an enum");
133 if (l_fund == ENUM && r_fund == ENUM) {
134 if (left->ex_type != right->ex_type)
135 warning("subtracting enums of different type");
136 /* update the type, cem does not do it */
137 expr->ex_type = int_type;
139 lint_enum_arith(l_fund, oper, r_fund);
144 lint_conversion(right, l_fund);
151 if (l_fund == ENUM || r_fund == ENUM)
152 warning("multiplying enum");
157 lint_conversion(right, l_fund);
159 if (l_fund == ENUM || r_fund == ENUM)
160 warning("division on enum");
164 lint_conversion(right, l_fund);
166 if (l_fund == ENUM || r_fund == ENUM)
167 warning("modulo on enum");
171 if (r_fund == ENUM || r_fund == FLOAT || r_fund == DOUBLE)
172 warning("~ on %s", symbol2str(r_fund));
177 warning("! on enum");
184 lint_conversion(right, l_fund);
193 if ( (l_fund == ENUM || r_fund == ENUM)
194 && left->ex_type != right->ex_type
196 warning("comparing enum with non-enum");
198 lint_relop(left, right, oper);
199 lint_relop(right, left,
202 oper == LESSEQ ? GREATEREQ :
203 oper == GREATEREQ ? LESSEQ :
210 lint_conversion(right, l_fund);
213 if (l_fund == ENUM || r_fund == ENUM)
214 warning("shift on enum");
220 lint_conversion(right, l_fund);
224 if (l_fund == ENUM || r_fund == ENUM)
225 warning("bit operations on enum");
247 lint_enum_arith(l_fund, oper, r_fund)
248 int l_fund, oper, r_fund;
255 warning("%s on enum and %s",
256 symbol2str(oper), symbol2str(r_fund));
264 warning("%s on %s and enum",
265 symbol2str(oper), symbol2str(l_fund));
270 lint_conversion(from_expr, to_fund)
271 struct expr *from_expr;
274 register int from_fund = from_expr->ex_type->tp_fund;
276 /* was there an attempt to reduce the type of the from_expr
279 or something like this?
281 if (from_expr->ex_class == Oper && from_expr->OP_OPER == INT2INT) {
282 from_expr = from_expr->OP_LEFT;
284 if (from_expr->ex_class == Oper && from_expr->OP_OPER == '&') {
286 is_cp_cst(from_expr->OP_LEFT) ? from_expr->OP_LEFT :
287 is_cp_cst(from_expr->OP_RIGHT) ? from_expr->OP_RIGHT :
291 arith val = bits->VL_VALUE;
299 if (numsize(from_fund) > numsize(to_fund)) {
300 awarning("conversion from %s to %s may lose accuracy",
301 symbol2str(from_fund), symbol2str(to_fund));
310 case SHORT: return 2;
314 case FLOAT: return 5;
315 case DOUBLE: return 6;
320 lint_ret_conv(from_expr)
321 struct expr *from_expr;
323 lint_conversion(from_expr, func_type->tp_fund);
326 lint_ptr_conv(from, to)
329 /* X -> X ok -- this includes struct -> struct, of any size
332 * FLOAT -> LONG -> INT -> SHORT ok
368 /* OK any which way */
372 hwarning("pointer to char may not align correctly for a %s",
376 warning("pointer to %s may not align correctly for a %s",
377 symbol2str(from), symbol2str(to));
381 lint_relop(left, right, oper)
382 struct expr *left, *right;
383 int oper; /* '<', '>', LESSEQ, GREATEREQ, EQUAL, NOTEQUAL */
385 /* left operand may be converted */
386 if ( left->ex_class == Oper
387 && left->OP_OPER == INT2INT
389 left = left->OP_RIGHT;
392 /* <unsigned> <relop> <neg-const|0> is doubtful */
393 if ( left->ex_type->tp_unsigned
394 && right->ex_class == Value
395 && right->VL_CLASS == Const
397 if (!right->ex_type->tp_unsigned && right->VL_VALUE < 0) {
398 warning("unsigned compared to negative constant");
400 if (right->VL_VALUE == 0) {
403 warning("unsigned < 0 will always fail");
407 warning("unsigned <= 0 is probably wrong");
411 warning("unsigned >= 0 will always succeed");
417 /* <char> <relop> <neg-const> is undefined */
418 if ( left->ex_type->tp_fund == CHAR
419 && right->ex_class == Value
420 && right->VL_CLASS == Const
421 && (right->VL_VALUE < 0 || right->VL_VALUE > 127)
423 warning("character compared to negative constant");