l_ev_ord.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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 evaluation order checking */
  7. #include "lint.h"
  8. #ifdef LINT
  9. #include <alloc.h> /* for st_free */
  10. #include "interface.h"
  11. #include "assert.h"
  12. #ifdef ANSI
  13. #include <flt_arith.h>
  14. #endif /* ANSI */
  15. #include "arith.h" /* definition arith */
  16. #include "label.h" /* definition label */
  17. #include "expr.h"
  18. #include "idf.h"
  19. #include "def.h"
  20. #include "code.h" /* RVAL etc */
  21. #include "LLlex.h"
  22. #include "Lpars.h"
  23. #include "stack.h"
  24. #include "type.h"
  25. #include "level.h"
  26. #include "l_lint.h"
  27. #include "l_state.h"
  28. extern char *symbol2str();
  29. PRIVATE check_ev_order();
  30. check_and_merge(expr, espp, esp)
  31. struct expr *expr;
  32. struct expr_state **espp, *esp;
  33. {
  34. /* Checks for undefined evaluation orders in case of a non-sequencing operator.
  35. * In addition the sets of used and set variables of both expressions are
  36. * united.
  37. * *espp will be pointing to this new list. esp is used for this list.
  38. */
  39. register struct expr_state **pp, *p1, *p2;
  40. int oper = expr->OP_OPER;
  41. int is_sequencer =
  42. (oper == '?' || oper == OR || oper == AND || oper ==',');
  43. for (p1 = *espp; p1; p1 = p1->next) {
  44. /* scan the list esp for the same variable */
  45. p2 = esp;
  46. pp = &esp;
  47. while (p2) {
  48. if ( /* p1 and p2 refer to the same location */
  49. p1->es_idf == p2->es_idf
  50. && p1->es_offset == p2->es_offset
  51. ) {
  52. /* check */
  53. if (!is_sequencer)
  54. check_ev_order(p1, p2, expr);
  55. /* merge the info */
  56. p1->es_used |= p2->es_used;
  57. p1->es_referred |= p2->es_referred;
  58. p1->es_set |= p2->es_set;
  59. /* and remove the entry from esp */
  60. *pp = p2->next;
  61. free_expr_state(p2);
  62. p2 = *pp;
  63. }
  64. else {
  65. /* skip over the entry in esp */
  66. pp = &p2->next;
  67. p2 = p2->next;
  68. }
  69. }
  70. }
  71. /* If there is anything left in the list esp, this is put in
  72. front of the list *espp is now pointing to, and *espp will be
  73. left pointing to this new list.
  74. */
  75. if (!esp)
  76. return;
  77. p1 = *espp;
  78. *espp = esp;
  79. while (esp->next)
  80. esp = esp->next;
  81. esp->next = p1;
  82. }
  83. PRIVATE
  84. check_ev_order(esp1, esp2, expr)
  85. struct expr_state *esp1, *esp2;
  86. struct expr *expr;
  87. {
  88. if ( (esp1->es_used && esp2->es_set)
  89. || (esp1->es_set && esp2->es_used)
  90. || (esp1->es_set && esp2->es_set)
  91. ) {
  92. expr_warning(expr,
  93. "result of %s depends on evaluation order on %s",
  94. symbol2str(expr->OP_OPER),
  95. esp1->es_idf->id_text);
  96. }
  97. }
  98. #endif /* LINT */