87_dead_code.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /* This checks various ways of dead code inside if statements
  2. where there are non-obvious ways of how the code is actually
  3. not dead due to reachable by labels. */
  4. extern int printf (const char *, ...);
  5. static void kb_wait_1(void)
  6. {
  7. unsigned long timeout = 2;
  8. do {
  9. /* Here the else arm is a statement expression that's supposed
  10. to be suppressed. The label inside the while would unsuppress
  11. code generation again if not handled correctly. And that
  12. would wreak havoc to the cond-expression because there's no
  13. jump-around emitted, the whole statement expression really
  14. needs to not generate code (perhaps except useless forward jumps). */
  15. (1 ?
  16. printf("timeout=%ld\n", timeout) :
  17. ({
  18. int i = 1;
  19. while (1)
  20. while (i--)
  21. some_label:
  22. printf("error\n");
  23. goto some_label;
  24. })
  25. );
  26. timeout--;
  27. } while (timeout);
  28. }
  29. int main (void)
  30. {
  31. int i = 1;
  32. kb_wait_1();
  33. /* Simple test of dead code at first sight which isn't actually dead. */
  34. if (0) {
  35. yeah:
  36. printf ("yeah\n");
  37. } else {
  38. printf ("boo\n");
  39. }
  40. if (i--)
  41. goto yeah;
  42. /* Some more non-obvious uses where the problems are loops, so that even
  43. the first loop statements aren't actually dead. */
  44. i = 1;
  45. if (0) {
  46. while (i--) {
  47. printf ("once\n");
  48. enterloop:
  49. printf ("twice\n");
  50. }
  51. }
  52. if (i >= 0)
  53. goto enterloop;
  54. /* The same with statement expressions. One might be tempted to
  55. handle them specially by counting if inside statement exprs and
  56. not unsuppressing code at loops at all then.
  57. See kb_wait_1 for the other side of the medal where that wouldn't work. */
  58. i = ({
  59. int j = 1;
  60. if (0) {
  61. while (j--) {
  62. printf ("SEonce\n");
  63. enterexprloop:
  64. printf ("SEtwice\n");
  65. }
  66. }
  67. if (j >= 0)
  68. goto enterexprloop;
  69. j; });
  70. /* The other two loop forms: */
  71. i = 1;
  72. if (0) {
  73. for (i = 1; i--;) {
  74. printf ("once2\n");
  75. enterloop2:
  76. printf ("twice2\n");
  77. }
  78. }
  79. if (i > 0)
  80. goto enterloop2;
  81. i = 1;
  82. if (0) {
  83. do {
  84. printf ("once3\n");
  85. enterloop3:
  86. printf ("twice3\n");
  87. } while (i--);
  88. }
  89. if (i > 0)
  90. goto enterloop3;
  91. /* And check that case and default labels have the same effect
  92. of disabling code suppression. */
  93. i = 41;
  94. switch (i) {
  95. if (0) {
  96. printf ("error\n");
  97. case 42:
  98. printf ("error2\n");
  99. case 41:
  100. printf ("caseok\n");
  101. }
  102. }
  103. i = 41;
  104. switch (i) {
  105. if (0) {
  106. printf ("error3\n");
  107. default:
  108. printf ("caseok2\n");
  109. break;
  110. case 42:
  111. printf ("error4\n");
  112. }
  113. }
  114. return 0;
  115. }