boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

00213.c (3110B)


      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 
     30 static int global;
     31 
     32 static void foo(int i)
     33 {
     34   global+=i;
     35   printf ("g=%d\n", global);
     36 }
     37 
     38 static int check(void)
     39 {
     40   printf ("check %d\n", global);
     41   return 1;
     42 }
     43 
     44 static void dowhile(void)
     45 {
     46   do {
     47       foo(1);
     48       if (global == 1) {
     49 	  continue;
     50       } else if (global == 2) {
     51 	  continue;
     52       }
     53       /* The following break shouldn't disable the check() call,
     54          as it's reachable by the continues above.  */
     55       break;
     56   } while (check());
     57 }
     58 
     59 int main (void)
     60 {
     61   int i = 1;
     62   kb_wait_1();
     63 
     64   /* Simple test of dead code at first sight which isn't actually dead. */
     65   if (0) {
     66 yeah:
     67       printf ("yeah\n");
     68   } else {
     69       printf ("boo\n");
     70   }
     71   if (i--)
     72     goto yeah;
     73 
     74   /* Some more non-obvious uses where the problems are loops, so that even
     75      the first loop statements aren't actually dead.  */
     76   i = 1;
     77   if (0) {
     78       while (i--) {
     79 	  printf ("once\n");
     80 enterloop:
     81 	  printf ("twice\n");
     82       }
     83   }
     84   if (i >= 0)
     85     goto enterloop;
     86 
     87   /* The same with statement expressions.  One might be tempted to
     88      handle them specially by counting if inside statement exprs and
     89      not unsuppressing code at loops at all then.
     90      See kb_wait_1 for the other side of the medal where that wouldn't work.  */
     91   i = ({
     92       int j = 1;
     93       if (0) {
     94 	  while (j--) {
     95 	      printf ("SEonce\n");
     96     enterexprloop:
     97 	      printf ("SEtwice\n");
     98 	  }
     99       }
    100       if (j >= 0)
    101 	goto enterexprloop;
    102       j; });
    103 
    104   /* The other two loop forms: */
    105   i = 1;
    106   if (0) {
    107       for (i = 1; i--;) {
    108 	  printf ("once2\n");
    109 enterloop2:
    110 	  printf ("twice2\n");
    111       }
    112   }
    113   if (i > 0)
    114     goto enterloop2;
    115 
    116   i = 1;
    117   if (0) {
    118       do {
    119 	  printf ("once3\n");
    120 enterloop3:
    121 	  printf ("twice3\n");
    122       } while (i--);
    123   }
    124   if (i > 0)
    125     goto enterloop3;
    126 
    127   /* And check that case and default labels have the same effect
    128      of disabling code suppression.  */
    129   i = 41;
    130   switch (i) {
    131       if (0) {
    132 	  printf ("error\n");
    133       case 42:
    134 	  printf ("error2\n");
    135       case 41:
    136 	  printf ("caseok\n");
    137       }
    138   }
    139 
    140   i = 41;
    141   switch (i) {
    142       if (0) {
    143 	  printf ("error3\n");
    144       default:
    145 	  printf ("caseok2\n");
    146 	  break;
    147       case 42:
    148 	  printf ("error4\n");
    149       }
    150   }
    151 
    152   dowhile();
    153 
    154   return 0;
    155 }