l_misc.c 8.3 KB

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