@@ -1767,7 +1767,8 @@ type elab_context = {
17671767 ctx_labels : StringSet .t ; (* *r all labels defined in the function *)
17681768 ctx_break : bool ; (* *r is 'break' allowed? *)
17691769 ctx_continue : bool ; (* *r is 'continue' allowed? *)
1770- ctx_in_switch : bool ; (* *r are 'case' and 'default' allowed? *)
1770+ ctx_in_switch : typ option ; (* *r type of the controlling switch expression
1771+ or [None] outside of switch *)
17711772 ctx_vararg : bool ; (* *r is this a vararg function? *)
17721773 ctx_nonstatic_inline : bool (* *r is this a nonstatic inline function? *)
17731774}
@@ -1777,7 +1778,7 @@ type elab_context = {
17771778let ctx_constexp = {
17781779 ctx_return_typ = TVoid [] ;
17791780 ctx_labels = StringSet. empty;
1780- ctx_break = false ; ctx_continue = false ; ctx_in_switch = false ;
1781+ ctx_break = false ; ctx_continue = false ; ctx_in_switch = None ;
17811782 ctx_vararg = false ; ctx_nonstatic_inline = false
17821783}
17831784
@@ -3063,7 +3064,7 @@ let stmt_labels stmt =
30633064
30643065let ctx_loop ctx = { ctx with ctx_break = true ; ctx_continue = true }
30653066
3066- let ctx_switch ctx = { ctx with ctx_break = true ; ctx_in_switch = true }
3067+ let ctx_switch ctx ty = { ctx with ctx_break = true ; ctx_in_switch = Some ty }
30673068
30683069(* Check the uniqueness of 'case' and 'default' in a 'switch' *)
30693070
@@ -3125,9 +3126,11 @@ let rec elab_stmt env ctx s =
31253126 { sdesc = Slabeled (Slabel lbl, s1); sloc = elab_loc loc },env
31263127
31273128 | CASE (a , s1 , loc ) ->
3128- if not ctx.ctx_in_switch then
3129- error loc " 'case' statement not in switch statement" ;
31303129 let a',env = elab_expr ctx loc env a in
3130+ let a' = match ctx.ctx_in_switch with
3131+ | None -> error loc " 'case' statement not in switch statement" ; a'
3132+ | Some ((TInt _ ) as ty ) -> ecast ty a'
3133+ | _ -> a' in
31313134 let n =
31323135 match Ceval. integer_expr env a' with
31333136 | None ->
@@ -3137,7 +3140,8 @@ let rec elab_stmt env ctx s =
31373140 { sdesc = Slabeled (Scase (a', n), s1); sloc = elab_loc loc },env
31383141
31393142 | DEFAULT (s1 , loc ) ->
3140- if not ctx.ctx_in_switch then
3143+ (* - #Link_to E_COMPCERT_TR_Robustness_ELAB_141 *)
3144+ if ctx.ctx_in_switch = None then
31413145 error loc " 'case' statement not in switch statement" ;
31423146 let s1,env = elab_stmt env ctx s1 in
31433147 { sdesc = Slabeled (Sdefault , s1); sloc = elab_loc loc },env
@@ -3217,7 +3221,7 @@ let rec elab_stmt env ctx s =
32173221 if not (is_integer_type env' a'.etyp) then
32183222 error loc " controlling expression of 'switch' does not have integer type (%a invalid)"
32193223 (print_typ env') a'.etyp;
3220- let s1' = elab_stmt_new_scope env' (ctx_switch ctx) s1 in
3224+ let s1' = elab_stmt_new_scope env' (ctx_switch ctx (unary_conversion env a'.etyp) ) s1 in
32213225 check_switch_cases s1';
32223226 { sdesc = Sswitch (a', s1'); sloc = elab_loc loc },env
32233227
@@ -3326,7 +3330,7 @@ let elab_funbody return_typ vararg nonstatic_inline env b =
33263330 ctx_labels = stmt_labels b;
33273331 ctx_break = false ;
33283332 ctx_continue = false ;
3329- ctx_in_switch = false ;
3333+ ctx_in_switch = None ;
33303334 ctx_vararg = vararg;
33313335 ctx_nonstatic_inline = nonstatic_inline } in
33323336 (* The function body appears as a block in the AST but should not create
0 commit comments