Skip to content

Commit f6a5780

Browse files
bschommerxavierleroy
authored andcommitted
Pass type of controlling switch expression into ctx.
The standard requires that the constant expression of a case needs to be converted to the integer promoted type of the controlling expression (§6.8.4.2p5). To enforce this we pass the ineger promoted type of the controlling expression in ctx and add a cast of the case expression to this type. If the controlling expression is not an integer type we already have an error message and skip adding the cast. Bug 40122
1 parent af865ad commit f6a5780

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

cparser/Elab.ml

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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 = {
17771778
let 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

30643065
let 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

Comments
 (0)