l_misc.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. /*
  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".
  4. */
  5. /* $Id$ */
  6. /* Lint miscellaneous routines */
  7. #include "lint.h"
  8. #ifdef LINT
  9. #include <alloc.h> /* for st_free */
  10. #include "interface.h"
  11. #ifdef ANSI
  12. #include <flt_arith.h>
  13. #endif /* ANSI */
  14. #include "arith.h" /* definition arith */
  15. #include "label.h" /* definition label */
  16. #include "expr.h"
  17. #include "idf.h"
  18. #include "def.h"
  19. #include "code.h" /* RVAL etc */
  20. #include "LLlex.h"
  21. #include "Lpars.h"
  22. #include "stack.h"
  23. #include "type.h"
  24. #include "level.h"
  25. #include "l_state.h"
  26. extern char *symbol2str();
  27. extern struct type *func_type;
  28. PRIVATE lint_enum_arith();
  29. PRIVATE lint_conversion();
  30. PRIVATE int numsize();
  31. check_hiding(idf, lvl, sc)
  32. struct idf *idf;
  33. int lvl;
  34. int sc;
  35. {
  36. /* Checks if there is already a definition for this non-extern
  37. name on a more global level.
  38. */
  39. struct def *def = idf->id_def;
  40. if ( def && def->df_level < lvl
  41. && ! ( lvl == L_FORMAL2
  42. || def->df_level == L_UNIVERSAL
  43. || sc == GLOBAL
  44. || sc == EXTERN
  45. )
  46. ) {
  47. warning("%s is already defined as a %s",
  48. idf->id_text,
  49. def->df_level == L_GLOBAL ? "global" :
  50. def->df_level == L_FORMAL2 ? "formal" :
  51. "more global local"
  52. );
  53. }
  54. }
  55. lint_new_oper(expr)
  56. struct expr *expr;
  57. {
  58. /* Does additional checking on a newly constructed expr node
  59. of class Oper.
  60. Some code in this routine could be contracted, but since
  61. I am not sure we have covered the entire ground, we'll
  62. leave the contracting for some rainy day.
  63. */
  64. register struct expr *left = expr->OP_LEFT;
  65. register struct expr *right = expr->OP_RIGHT;
  66. register int oper = expr->OP_OPER;
  67. register int l_fund =
  68. left == 0 ? 0 : /* for monadics */
  69. left->ex_type->tp_fund;
  70. register int r_fund =
  71. right == 0 ? 0 : /* for ( without parameters */
  72. right->ex_type->tp_fund;
  73. /* In ch7.c, in ch7asgn(), a combined operator/assignment
  74. is hammered into correctness by repeated application of
  75. ch7bin(), which calls new_oper(), which calls lint_new_oper().
  76. These spurious calls understandably cause spurious error
  77. messages, which we don't like. So we try to suppress these
  78. wierd calls here. This refers to the code marked
  79. this is really $#@&*%$# !
  80. in ch7asgn().
  81. */
  82. switch (oper) {
  83. case PLUSAB:
  84. case MINAB:
  85. case TIMESAB:
  86. case DIVAB:
  87. case MODAB:
  88. case LEFTAB:
  89. case RIGHTAB:
  90. case ANDAB:
  91. case XORAB:
  92. case ORAB:
  93. /* is the left operand wierd? */
  94. if ( left->ex_class == Value
  95. && left->VL_CLASS == Const
  96. && left->VL_VALUE == 0
  97. ) {
  98. return;
  99. }
  100. }
  101. switch (oper) {
  102. case '=':
  103. lint_conversion(right, l_fund);
  104. break;
  105. case PLUSAB:
  106. lint_conversion(right, l_fund);
  107. case '+':
  108. lint_enum_arith(l_fund, oper, r_fund);
  109. break;
  110. case MINAB:
  111. lint_conversion(right, l_fund);
  112. case '-':
  113. if (left == 0) {
  114. /* unary */
  115. if (r_fund == ENUM)
  116. warning("negating an enum");
  117. }
  118. else {
  119. /* binary */
  120. if (l_fund == ENUM && r_fund == ENUM) {
  121. if (left->ex_type != right->ex_type)
  122. warning("subtracting enums of different type");
  123. /* update the type, cem does not do it */
  124. expr->ex_type = int_type;
  125. }
  126. lint_enum_arith(l_fund, oper, r_fund);
  127. }
  128. break;
  129. case TIMESAB:
  130. lint_conversion(right, l_fund);
  131. case '*':
  132. if (left == 0) {
  133. /* unary */
  134. }
  135. else {
  136. /* binary */
  137. if (l_fund == ENUM || r_fund == ENUM)
  138. warning("multiplying enum");
  139. }
  140. break;
  141. case DIVAB:
  142. lint_conversion(right, l_fund);
  143. case '/':
  144. if (l_fund == ENUM || r_fund == ENUM)
  145. warning("division on enum");
  146. break;
  147. case MODAB:
  148. lint_conversion(right, l_fund);
  149. case '%':
  150. if (l_fund == ENUM || r_fund == ENUM)
  151. warning("modulo on enum");
  152. break;
  153. case '~':
  154. if (r_fund == ENUM || r_fund == FLOAT || r_fund == DOUBLE)
  155. warning("~ on %s", symbol2str(r_fund));
  156. break;
  157. case '!':
  158. if (r_fund == ENUM)
  159. warning("! on enum");
  160. break;
  161. case INT2INT:
  162. case INT2FLOAT:
  163. case FLOAT2INT:
  164. case FLOAT2FLOAT:
  165. lint_conversion(right, l_fund);
  166. break;
  167. case '<':
  168. case '>':
  169. case LESSEQ:
  170. case GREATEREQ:
  171. case EQUAL:
  172. case NOTEQUAL:
  173. if ( (l_fund == ENUM || r_fund == ENUM)
  174. && left->ex_type != right->ex_type
  175. ) {
  176. warning("comparing enum with non-enum");
  177. }
  178. lint_relop(left, right, oper);
  179. lint_relop(right, left,
  180. oper == '<' ? '>' :
  181. oper == '>' ? '<' :
  182. oper == LESSEQ ? GREATEREQ :
  183. oper == GREATEREQ ? LESSEQ :
  184. oper
  185. );
  186. break;
  187. case LEFTAB:
  188. case RIGHTAB:
  189. lint_conversion(right, l_fund);
  190. case LEFT:
  191. case RIGHT:
  192. if (l_fund == ENUM || r_fund == ENUM)
  193. warning("shift on enum");
  194. break;
  195. case ANDAB:
  196. case ORAB:
  197. case XORAB:
  198. lint_conversion(right, l_fund);
  199. case '&':
  200. case '|':
  201. case '^':
  202. if (l_fund == ENUM || r_fund == ENUM)
  203. warning("bit operations on enum");
  204. break;
  205. case ',':
  206. case '?':
  207. case ':':
  208. case AND:
  209. case OR:
  210. case POSTINCR:
  211. case POSTDECR:
  212. case PLUSPLUS:
  213. case MINMIN:
  214. case '(':
  215. case '.':
  216. case ARROW:
  217. default:
  218. /* OK with lint */
  219. break;
  220. }
  221. }
  222. PRIVATE
  223. lint_enum_arith(l_fund, oper, r_fund)
  224. int l_fund, oper, r_fund;
  225. {
  226. if ( l_fund == ENUM
  227. && r_fund != CHAR
  228. && r_fund != SHORT
  229. && r_fund != INT
  230. ) {
  231. warning("%s on enum and %s",
  232. symbol2str(oper), symbol2str(r_fund));
  233. }
  234. else
  235. if ( r_fund == ENUM
  236. && l_fund != CHAR
  237. && l_fund != SHORT
  238. && l_fund != INT
  239. ) {
  240. warning("%s on %s and enum",
  241. symbol2str(oper), symbol2str(l_fund));
  242. }
  243. }
  244. PRIVATE
  245. lint_conversion(from_expr, to_fund)
  246. struct expr *from_expr;
  247. int to_fund;
  248. {
  249. register int from_fund = from_expr->ex_type->tp_fund;
  250. /* was there an attempt to reduce the type of the from_expr
  251. of the form
  252. expr & 0377
  253. or something like this?
  254. */
  255. if (from_expr->ex_class == Oper && from_expr->OP_OPER == INT2INT) {
  256. from_expr = from_expr->OP_LEFT;
  257. }
  258. if (from_expr->ex_class == Oper && from_expr->OP_OPER == '&') {
  259. struct expr *bits =
  260. is_cp_cst(from_expr->OP_LEFT) ? from_expr->OP_LEFT :
  261. is_cp_cst(from_expr->OP_RIGHT) ? from_expr->OP_RIGHT :
  262. 0;
  263. if (bits) {
  264. arith val = bits->VL_VALUE;
  265. if (val < 256)
  266. from_fund = CHAR;
  267. else if (val < 256)
  268. from_fund = SHORT;
  269. }
  270. }
  271. if (numsize(from_fund) > numsize(to_fund)) {
  272. awarning("conversion from %s to %s may lose accuracy",
  273. symbol2str(from_fund), symbol2str(to_fund));
  274. }
  275. }
  276. PRIVATE int
  277. numsize(fund)
  278. {
  279. switch (fund) {
  280. case CHAR: return 1;
  281. case SHORT: return 2;
  282. case INT: return 3;
  283. case ENUM: return 3;
  284. case LONG: return 4;
  285. case FLOAT: return 5;
  286. case DOUBLE: return 6;
  287. default: return 0;
  288. }
  289. }
  290. lint_ret_conv(from_expr)
  291. struct expr *from_expr;
  292. {
  293. lint_conversion(from_expr, func_type->tp_fund);
  294. }
  295. lint_ptr_conv(from, to)
  296. short from, to;
  297. {
  298. /* X -> X ok -- this includes struct -> struct, of any size
  299. * X -> CHAR ok
  300. * DOUBLE -> X ok
  301. * FLOAT -> LONG -> INT -> SHORT ok
  302. */
  303. if (from == to)
  304. return;
  305. if (to == VOID)
  306. return;
  307. if (to == CHAR)
  308. return;
  309. if (from == DOUBLE)
  310. return;
  311. switch (from) {
  312. case FLOAT:
  313. switch (to) {
  314. case LONG:
  315. case INT:
  316. case SHORT:
  317. return;
  318. }
  319. break;
  320. case LONG:
  321. switch (to) {
  322. case INT:
  323. case SHORT:
  324. return;
  325. }
  326. break;
  327. case INT:
  328. switch (to) {
  329. case SHORT:
  330. return;
  331. }
  332. break;
  333. }
  334. if (from == VOID) {
  335. /* OK any which way */
  336. }
  337. else
  338. if (from == CHAR) {
  339. hwarning("pointer to char may not align correctly for a %s",
  340. symbol2str(to));
  341. }
  342. else {
  343. warning("pointer to %s may not align correctly for a %s",
  344. symbol2str(from), symbol2str(to));
  345. }
  346. }
  347. lint_relop(left, right, oper)
  348. struct expr *left, *right;
  349. int oper; /* '<', '>', LESSEQ, GREATEREQ, EQUAL, NOTEQUAL */
  350. {
  351. /* left operand may be converted */
  352. if ( left->ex_class == Oper
  353. && left->OP_OPER == INT2INT
  354. ) {
  355. left = left->OP_RIGHT;
  356. }
  357. /* <unsigned> <relop> <neg-const|0> is doubtful */
  358. if ( left->ex_type->tp_unsigned
  359. && right->ex_class == Value
  360. && right->VL_CLASS == Const
  361. ) {
  362. if (!right->ex_type->tp_unsigned && right->VL_VALUE < 0) {
  363. warning("unsigned compared to negative constant");
  364. }
  365. if (right->VL_VALUE == 0) {
  366. switch (oper) {
  367. case '<':
  368. warning("unsigned < 0 will always fail");
  369. break;
  370. case LESSEQ:
  371. warning("unsigned <= 0 is probably wrong");
  372. break;
  373. case GREATEREQ:
  374. warning("unsigned >= 0 will always succeed");
  375. break;
  376. }
  377. }
  378. }
  379. /* <char> <relop> <neg-const> is undefined */
  380. if ( left->ex_type->tp_fund == CHAR
  381. && right->ex_class == Value
  382. && right->VL_CLASS == Const
  383. && (right->VL_VALUE < 0 || right->VL_VALUE > 127)
  384. ) {
  385. warning("character compared to negative constant");
  386. }
  387. }
  388. #endif /* LINT */