SwitchStmt bug?

Hi all,

I was inspecting the AST dump of this switch:

void test_switch(int t) {
switch(t)
{
case 1:
y = 11;
case 2:
y = 9;
x = 12;
break;
default:
break;
}
}

and I got something I didn’t expect. The second CaseStmt does only contain the first statement that is under it’s label. The “x=12;” gets its own Stmt outside the CaseStmt but inside the CompoundStmt inside the SwitchStmt. I would anticipate that all statements under a label either are: inside the CaseStmt or: outside but inside the CompoundStmt. Any reason for this?.

SwitchStmt 0x5bf6fe8

-<<>>
-ImplicitCastExpr 0x5bf6fd0 ‘int’
-DeclRefExpr 0x5bf6fa8 'int' lvalue ParmVar 0x5bf6e80 't' 'int' -CompoundStmt 0x5bf7258
-CaseStmt 0x5bf7038

-IntegerLiteral 0x5bf7018 ‘int’ 1
-<<>>
-BinaryOperator 0x5bf70b8 'int' lvalue '=' -DeclRefExpr 0x5bf7070 'int' lvalue Var 0x5bf6cf0 'y' 'int' -IntegerLiteral 0x5bf7098 ‘int’ 11
-CaseStmt 0x5bf7100
-IntegerLiteral 0x5bf70e0 ‘int’ 2
-<<>>
-BinaryOperator 0x5bf7180 'int' lvalue '=' -DeclRefExpr 0x5bf7138 'int' lvalue Var 0x5bf6cf0 'y' 'int' -IntegerLiteral 0x5bf7160 ‘int’ 9
-BinaryOperator 0x5bf71f0 ‘int’ lvalue ‘=’
-DeclRefExpr 0x5bf71a8 ‘int’ lvalue Var 0x5bf6e10 ‘x’ ‘int’
-IntegerLiteral 0x5bf71d0 'int' 12 -BreakStmt 0x5bf7218 -DefaultStmt 0x5bf7238
`-BreakStmt 0x5bf7228

Best regards,
Per Viberg


Per Viberg Senior Engineer
Evidente ES East AB Warfvinges väg 34 SE-112 51 Stockholm Sweden

Phone: +46 (0)8 402 79 00
Mobile: +46 (0)70 912 42 52
E-mail: Per.Viberg@evidente.se

www.evidente.se

This e-mail, which might contain confidential information, is addressed to the above stated person/company. If you are not the correct addressee, employee or in any other way the person concerned, please notify the sender immediately. At the same time, please delete this e-mail and destroy any prints. Thank You.

Hi all,

I was inspecting the AST dump of this switch:

void test_switch(int t) {
   switch(t)
   {
   case 1:
     y = 11;
   case 2:
     y = 9;
     x = 12;
     break;
   default:
     break;
   }
}

and I got something I didn't expect. The second CaseStmt does only
contain the first statement that is under it's label. The "x=12;" gets
its own Stmt outside the CaseStmt but inside the CompoundStmt inside the
SwitchStmt. I would anticipate that all statements under a label either
are: inside the CaseStmt or: outside but inside the CompoundStmt. Any
reason for this?.

This is expected. Case statements have just one sub statement.

The statements can be grouped with the case statement through the use of a compound statement:

$ cat t.c
int x;
int y;
void test_switch(int t) {
    switch(t)
    {
    case 1:
      y = 11;
    case 2: { // Start compound statement
      y = 9;
      x = 12;
      break;
    } // End compound statement
    default:
      break;
    }
}

$ clang -Xclang -ast-dump -c t.c
...
     `-SwitchStmt 0x5a03748 <line:4:4, line:15:4>
       >-<<<NULL>>>
       >-ImplicitCastExpr 0x5a03730 <line:4:11> 'int' <LValueToRValue>
       > `-DeclRefExpr 0x5a03708 <col:11> 'int' lvalue ParmVar 0x5a035a0 't' 'int'
       `-CompoundStmt 0x5a4ab58 <line:5:4, line:15:4>
         >-CaseStmt 0x5a03798 <line:6:4, line:7:10>
         > >-IntegerLiteral 0x5a03778 <line:6:9> 'int' 1
         > >-<<<NULL>>>
         > `-BinaryOperator 0x5a03818 <line:7:6, col:10> 'int' '='
         > >-DeclRefExpr 0x5a037d0 <col:6> 'int' lvalue Var 0x5a03530 'y' 'int'
         > `-IntegerLiteral 0x5a037f8 <col:10> 'int' 11
         >-CaseStmt 0x5a03860 <line:8:4, line:12:4>
         > >-IntegerLiteral 0x5a03840 <line:8:9> 'int' 2
         > >-<<<NULL>>>
         > `-CompoundStmt 0x5a4aaf8 <col:12, line:12:4>
         > >-BinaryOperator 0x5a4aa50 <line:9:6, col:10> 'int' '='
         > > >-DeclRefExpr 0x5a03898 <col:6> 'int' lvalue Var 0x5a03530 'y' 'int'
         > > `-IntegerLiteral 0x5a038c0 <col:10> 'int' 9
         > >-BinaryOperator 0x5a4aac0 <line:10:6, col:10> 'int' '='
         > > >-DeclRefExpr 0x5a4aa78 <col:6> 'int' lvalue Var 0x5a034c0 'x' 'int'
         > > `-IntegerLiteral 0x5a4aaa0 <col:10> 'int' 12
         > `-BreakStmt 0x5a4aae8 <line:11:6>
         `-DefaultStmt 0x5a4ab38 <line:13:4, line:14:6>
           `-BreakStmt 0x5a4ab28 <col:6>

Tom.

More generally, case statements are just labels, and have the same basic rules as regular old goto labels. Having case statements “just” be labels is what allows things like Duff’s Device in C:

switch(count % 8) {
case 0: do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while(–n > 0);
}

This is the opposite situation, really, because here we need cases inside the loop that’s inside the switch. But once you’re supporting this, the representation as a simple label is just easier to work with.

Jordan

thanks guys for the quick reply,

yeah, I suspected something like that. The only thing I was surprised about was that there is a Stmt at all inside a switch “label”. I mean, if they are just like goto labels, then no statement at all would seem more intuitive.


Per Viberg Senior Engineer
Evidente ES East AB Warfvinges väg 34 SE-112 51 Stockholm Sweden

Phone: +46 (0)8 402 79 00
Mobile: +46 (0)70 912 42 52
E-mail: Per.Viberg@evidente.se

www.evidente.se

This e-mail, which might contain confidential information, is addressed to the above stated person/company. If you are not the correct addressee, employee or in any other way the person concerned, please notify the sender immediately. At the same time, please delete this e-mail and destroy any prints. Thank You.

thanks guys for the quick reply,

yeah, I suspected something like that. The only thing I was surprised
about was that there is a Stmt at all inside a switch "label". I mean, if
they are just like goto labels, then no statement at all would seem more
intuitive.

Consider this:

switch (x) {
  if (a)
    case 1: b;
  c;
}

An 'if' statement can only have one substatement, so the case label *must*
have 'b' as its child or we'd have no way to represent this code. And the
case label must *not* have 'c' as its child, or we'd be representing this
incorrectly.

Also, the relevant language standards say that labels have a single
statement as a child, and we try to make our representations faithful to
the relevant standards as far as is reasonably possible.

thanks for the clarification Richard, it helped.

I consider the question here by answered.


Per Viberg Senior Engineer
Evidente ES East AB Warfvinges väg 34 SE-112 51 Stockholm Sweden

Phone: +46 (0)8 402 79 00
Mobile: +46 (0)70 912 42 52
E-mail: Per.Viberg@evidente.se

www.evidente.se

This e-mail, which might contain confidential information, is addressed to the above stated person/company. If you are not the correct addressee, employee or in any other way the person concerned, please notify the sender immediately. At the same time, please delete this e-mail and destroy any prints. Thank You.